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 code import Code | 5 from code import Code |
6 from model import PropertyType | 6 from model import PropertyType |
7 import cpp_util | 7 import cpp_util |
8 import schema_util | 8 import schema_util |
9 import util_cc_helper | 9 import util_cc_helper |
10 | 10 |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 if underlying_type.property_type == PropertyType.ENUM: | 359 if underlying_type.property_type == PropertyType.ENUM: |
360 c.Sblock('if (%s != %s) {' % | 360 c.Sblock('if (%s != %s) {' % |
361 (prop_var, | 361 (prop_var, |
362 self._type_helper.GetEnumNoneValue(prop.type_))) | 362 self._type_helper.GetEnumNoneValue(prop.type_))) |
363 else: | 363 else: |
364 c.Sblock('if (%s.get()) {' % prop_var) | 364 c.Sblock('if (%s.get()) {' % prop_var) |
365 | 365 |
366 # ANY is a base::Value which is abstract and cannot be a direct member, so | 366 # ANY is a base::Value which is abstract and cannot be a direct member, so |
367 # it will always be a pointer. | 367 # it will always be a pointer. |
368 is_ptr = prop.optional or prop.type_.property_type == PropertyType.ANY | 368 is_ptr = prop.optional or prop.type_.property_type == PropertyType.ANY |
369 c.Append('value->SetWithoutPathExpansion("%s", %s);' % ( | 369 c.Cblock(self._CreateValueFromType( |
| 370 'value->SetWithoutPathExpansion("%s", %%s);' % prop.name, |
370 prop.name, | 371 prop.name, |
371 self._CreateValueFromType(cpp_namespace, | 372 prop.type_, |
372 prop.type_, | 373 prop_var, |
373 prop_var, | 374 is_ptr=is_ptr)) |
374 is_ptr=is_ptr))) | |
375 | 375 |
376 if prop.optional: | 376 if prop.optional: |
377 c.Eblock('}') | 377 c.Eblock('}') |
378 | 378 |
379 if type_.additional_properties is not None: | 379 if type_.additional_properties is not None: |
380 if type_.additional_properties.property_type == PropertyType.ANY: | 380 if type_.additional_properties.property_type == PropertyType.ANY: |
381 c.Append('value->MergeDictionary(&additional_properties);') | 381 c.Append('value->MergeDictionary(&additional_properties);') |
382 else: | 382 else: |
383 # Non-copyable types will be wrapped in a linked_ptr for inclusion in | 383 # Non-copyable types will be wrapped in a linked_ptr for inclusion in |
384 # maps, so we need to unwrap them. | 384 # maps, so we need to unwrap them. |
385 needs_unwrap = ( | 385 needs_unwrap = ( |
386 not self._type_helper.IsCopyable(type_.additional_properties)) | 386 not self._type_helper.IsCopyable(type_.additional_properties)) |
387 cpp_type = self._type_helper.GetCppType(type_.additional_properties, | 387 cpp_type = self._type_helper.GetCppType(type_.additional_properties, |
388 is_in_container=True) | 388 is_in_container=True) |
389 (c.Sblock('for (std::map<std::string, %s>::const_iterator it =' % | 389 (c.Sblock('for (std::map<std::string, %s>::const_iterator it =' % |
390 cpp_util.PadForGenerics(cpp_type)) | 390 cpp_util.PadForGenerics(cpp_type)) |
391 .Append(' additional_properties.begin();') | 391 .Append(' additional_properties.begin();') |
392 .Append(' it != additional_properties.end(); ++it) {') | 392 .Append(' it != additional_properties.end(); ++it) {') |
393 .Append('value->SetWithoutPathExpansion(it->first, %s);' % | 393 .Cblock(self._CreateValueFromType( |
394 self._CreateValueFromType( | 394 'value->SetWithoutPathExpansion(it->first, %s);', |
395 cpp_namespace, | 395 type_.additional_properties.name, |
396 type_.additional_properties, | 396 type_.additional_properties, |
397 '%sit->second' % ('*' if needs_unwrap else ''))) | 397 '%sit->second' % ('*' if needs_unwrap else ''))) |
398 .Eblock('}') | 398 .Eblock('}') |
399 ) | 399 ) |
400 | 400 |
401 return (c.Append() | 401 return (c.Append() |
402 .Append('return value.Pass();') | 402 .Append('return value.Pass();') |
403 .Eblock('}')) | 403 .Eblock('}')) |
404 | 404 |
405 def _GenerateChoiceTypeToValue(self, cpp_namespace, type_): | 405 def _GenerateChoiceTypeToValue(self, cpp_namespace, type_): |
406 """Generates a function that serializes a choice-representing type | 406 """Generates a function that serializes a choice-representing type |
407 into a base::Value. | 407 into a base::Value. |
408 """ | 408 """ |
409 c = Code() | 409 c = Code() |
410 c.Sblock('scoped_ptr<base::Value> %s::ToValue() const {' % cpp_namespace) | 410 c.Sblock('scoped_ptr<base::Value> %s::ToValue() const {' % cpp_namespace) |
411 c.Append('scoped_ptr<base::Value> result;') | 411 c.Append('scoped_ptr<base::Value> result;') |
412 for choice in type_.choices: | 412 for choice in type_.choices: |
413 choice_var = 'as_%s' % choice.unix_name | 413 choice_var = 'as_%s' % choice.unix_name |
414 (c.Sblock('if (%s) {' % choice_var) | 414 (c.Sblock('if (%s) {' % choice_var) |
415 .Append('DCHECK(!result) << "Cannot set multiple choices for %s";' % | 415 .Append('DCHECK(!result) << "Cannot set multiple choices for %s";' % |
416 type_.unix_name) | 416 type_.unix_name) |
417 .Append('result.reset(%s);' % self._CreateValueFromType( | 417 .Cblock(self._CreateValueFromType('result.reset(%s);', |
418 cpp_namespace, | 418 choice.name, |
419 choice, | 419 choice, |
420 '*%s' % choice_var)) | 420 '*%s' % choice_var)) |
421 .Eblock('}') | 421 .Eblock('}') |
422 ) | 422 ) |
423 (c.Append('DCHECK(result) << "Must set at least one choice for %s";' % | 423 (c.Append('DCHECK(result) << "Must set at least one choice for %s";' % |
424 type_.unix_name) | 424 type_.unix_name) |
425 .Append('return result.Pass();') | 425 .Append('return result.Pass();') |
426 .Eblock('}') | 426 .Eblock('}') |
427 ) | 427 ) |
428 return c | 428 return c |
429 | 429 |
430 def _GenerateFunction(self, function): | 430 def _GenerateFunction(self, function): |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 (c.Append('namespace %s {' % event_namespace) | 467 (c.Append('namespace %s {' % event_namespace) |
468 .Append() | 468 .Append() |
469 .Cblock(self._GenerateEventNameConstant(None, event)) | 469 .Cblock(self._GenerateEventNameConstant(None, event)) |
470 .Cblock(self._GenerateCreateCallbackArguments(event_namespace, | 470 .Cblock(self._GenerateCreateCallbackArguments(event_namespace, |
471 None, | 471 None, |
472 event)) | 472 event)) |
473 .Append('} // namespace %s' % event_namespace) | 473 .Append('} // namespace %s' % event_namespace) |
474 ) | 474 ) |
475 return c | 475 return c |
476 | 476 |
477 def _CreateValueFromType(self, cpp_namespace, type_, var, is_ptr=False): | 477 def _CreateValueFromType(self, code, prop_name, type_, var, is_ptr=False): |
478 """Creates a base::Value given a type. Generated code passes ownership | 478 """Creates a base::Value given a type. Generated code passes ownership |
479 to caller. | 479 to caller. |
480 | 480 |
481 var: variable or variable* | 481 var: variable or variable* |
482 | 482 |
483 E.g for std::string, generate new base::StringValue(var) | 483 E.g for std::string, generate new base::StringValue(var) |
484 """ | 484 """ |
| 485 c = Code() |
| 486 underlying_type = self._type_helper.FollowRef(type_) |
| 487 if underlying_type.property_type == PropertyType.ARRAY: |
| 488 # Enums are treated specially because C++ templating thinks that they're |
| 489 # ints, but really they're strings. So we create a vector of strings and |
| 490 # populate it with the names of the enum in the array. The |ToString| |
| 491 # function of the enum can be in another namespace when the enum is |
| 492 # referenced. Templates can not be used here because C++ templating does |
| 493 # not support passing a namespace as an argument. |
| 494 item_type = self._type_helper.FollowRef(underlying_type.item_type) |
| 495 if item_type.property_type == PropertyType.ENUM: |
| 496 vardot = '(%s)%s' % (var, '->' if is_ptr else '.') |
| 497 |
| 498 maybe_namespace = '' |
| 499 if type_.item_type.property_type == PropertyType.REF: |
| 500 maybe_namespace = '%s::' % item_type.namespace.unix_name |
| 501 |
| 502 enum_list_var = '%s_list' % prop_name |
| 503 # Scope the std::vector variable declaration inside braces. |
| 504 (c.Sblock('{') |
| 505 .Append('std::vector<std::string> %s;' % enum_list_var) |
| 506 .Append('for (std::vector<%s>::const_iterator it = %sbegin();' |
| 507 % (self._type_helper.GetCppType(item_type), vardot)) |
| 508 .Sblock(' it != %send(); ++it) {' % vardot) |
| 509 .Append('%s.push_back(%sToString(*it));' % (enum_list_var, |
| 510 maybe_namespace)) |
| 511 .Eblock('}')) |
| 512 |
| 513 # Because the std::vector above is always created for both required and |
| 514 # optional enum arrays, |is_ptr| is set to false and uses the |
| 515 # std::vector to create the values. |
| 516 (c.Append(code % |
| 517 self._GenerateCreateValueFromType(type_, enum_list_var, False)) |
| 518 .Eblock('}')) |
| 519 return c |
| 520 |
| 521 c.Append(code % self._GenerateCreateValueFromType(type_, var, is_ptr)) |
| 522 return c |
| 523 |
| 524 def _GenerateCreateValueFromType(self, type_, var, is_ptr): |
| 525 """Generates the statement to create a base::Value given a type. |
| 526 |
| 527 type_: The type of the values being converted. |
| 528 var: The name of the variable. |
| 529 is_ptr: Whether |type_| is optional. |
| 530 """ |
485 underlying_type = self._type_helper.FollowRef(type_) | 531 underlying_type = self._type_helper.FollowRef(type_) |
486 if (underlying_type.property_type == PropertyType.CHOICES or | 532 if (underlying_type.property_type == PropertyType.CHOICES or |
487 underlying_type.property_type == PropertyType.OBJECT): | 533 underlying_type.property_type == PropertyType.OBJECT): |
488 if is_ptr: | 534 if is_ptr: |
489 return '(%s)->ToValue().release()' % var | 535 return '(%s)->ToValue().release()' % var |
490 else: | 536 else: |
491 return '(%s).ToValue().release()' % var | 537 return '(%s).ToValue().release()' % var |
492 elif (underlying_type.property_type == PropertyType.ANY or | 538 elif (underlying_type.property_type == PropertyType.ANY or |
493 underlying_type.property_type == PropertyType.FUNCTION): | 539 underlying_type.property_type == PropertyType.FUNCTION): |
494 if is_ptr: | 540 if is_ptr: |
495 vardot = '(%s)->' % var | 541 vardot = '(%s)->' % var |
496 else: | 542 else: |
497 vardot = '(%s).' % var | 543 vardot = '(%s).' % var |
498 return '%sDeepCopy()' % vardot | 544 return '%sDeepCopy()' % vardot |
499 elif underlying_type.property_type == PropertyType.ENUM: | 545 elif underlying_type.property_type == PropertyType.ENUM: |
500 maybe_namespace = '' | 546 maybe_namespace = '' |
501 if type_.property_type == PropertyType.REF: | 547 if type_.property_type == PropertyType.REF: |
502 maybe_namespace = '%s::' % underlying_type.namespace.unix_name | 548 maybe_namespace = '%s::' % underlying_type.namespace.unix_name |
503 return 'new base::StringValue(%sToString(%s))' % (maybe_namespace, var) | 549 return 'new base::StringValue(%sToString(%s))' % (maybe_namespace, var) |
504 elif underlying_type.property_type == PropertyType.BINARY: | 550 elif underlying_type.property_type == PropertyType.BINARY: |
505 if is_ptr: | 551 if is_ptr: |
506 vardot = var + '->' | 552 vardot = var + '->' |
507 else: | 553 else: |
508 vardot = var + '.' | 554 vardot = var + '.' |
509 return ('base::BinaryValue::CreateWithCopiedBuffer(%sdata(), %ssize())' % | 555 return ('base::BinaryValue::CreateWithCopiedBuffer(%sdata(), %ssize())' % |
510 (vardot, vardot)) | 556 (vardot, vardot)) |
511 elif underlying_type.property_type == PropertyType.ARRAY: | 557 elif underlying_type.property_type == PropertyType.ARRAY: |
512 return '%s.release()' % self._util_cc_helper.CreateValueFromArray( | 558 return '%s.release()' % self._util_cc_helper.CreateValueFromArray( |
513 cpp_namespace, | |
514 underlying_type, | |
515 var, | 559 var, |
516 is_ptr) | 560 is_ptr) |
517 elif underlying_type.property_type.is_fundamental: | 561 elif underlying_type.property_type.is_fundamental: |
518 if is_ptr: | 562 if is_ptr: |
519 var = '*%s' % var | 563 var = '*%s' % var |
520 if underlying_type.property_type == PropertyType.STRING: | 564 if underlying_type.property_type == PropertyType.STRING: |
521 return 'new base::StringValue(%s)' % var | 565 return 'new base::StringValue(%s)' % var |
522 else: | 566 else: |
523 return 'new base::FundamentalValue(%s)' % var | 567 return 'new base::FundamentalValue(%s)' % var |
524 else: | 568 else: |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
952 | 996 |
953 (c.Sblock('scoped_ptr<base::ListValue> %(function_scope)s' | 997 (c.Sblock('scoped_ptr<base::ListValue> %(function_scope)s' |
954 'Create(%(declaration_list)s) {') | 998 'Create(%(declaration_list)s) {') |
955 .Append('scoped_ptr<base::ListValue> create_results(' | 999 .Append('scoped_ptr<base::ListValue> create_results(' |
956 'new base::ListValue());') | 1000 'new base::ListValue());') |
957 ) | 1001 ) |
958 declaration_list = [] | 1002 declaration_list = [] |
959 for param in params: | 1003 for param in params: |
960 declaration_list.append(cpp_util.GetParameterDeclaration( | 1004 declaration_list.append(cpp_util.GetParameterDeclaration( |
961 param, self._type_helper.GetCppType(param.type_))) | 1005 param, self._type_helper.GetCppType(param.type_))) |
962 c.Append('create_results->Append(%s);' % self._CreateValueFromType( | 1006 c.Cblock(self._CreateValueFromType('create_results->Append(%s);', |
963 cpp_namespace, | 1007 param.name, |
964 param.type_, | 1008 param.type_, |
965 param.unix_name)) | 1009 param.unix_name)) |
966 c.Append('return create_results.Pass();') | 1010 c.Append('return create_results.Pass();') |
967 c.Eblock('}') | 1011 c.Eblock('}') |
968 c.Substitute({ | 1012 c.Substitute({ |
969 'function_scope': ('%s::' % function_scope) if function_scope else '', | 1013 'function_scope': ('%s::' % function_scope) if function_scope else '', |
970 'declaration_list': ', '.join(declaration_list), | 1014 'declaration_list': ', '.join(declaration_list), |
971 'param_names': ', '.join(param.unix_name for param in params) | 1015 'param_names': ', '.join(param.unix_name for param in params) |
972 }) | 1016 }) |
973 return c | 1017 return c |
974 | 1018 |
975 def _GenerateEventNameConstant(self, function_scope, event): | 1019 def _GenerateEventNameConstant(self, function_scope, event): |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1016 if self._generate_error_messages: | 1060 if self._generate_error_messages: |
1017 params = list(params) + ['base::string16* error'] | 1061 params = list(params) + ['base::string16* error'] |
1018 return ', '.join(str(p) for p in params) | 1062 return ', '.join(str(p) for p in params) |
1019 | 1063 |
1020 def _GenerateArgs(self, args): | 1064 def _GenerateArgs(self, args): |
1021 """Builds the argument list for a function, given an array of arguments. | 1065 """Builds the argument list for a function, given an array of arguments. |
1022 """ | 1066 """ |
1023 if self._generate_error_messages: | 1067 if self._generate_error_messages: |
1024 args = list(args) + ['error'] | 1068 args = list(args) + ['error'] |
1025 return ', '.join(str(a) for a in args) | 1069 return ', '.join(str(a) for a in args) |
OLD | NEW |