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 (typename std::vector<%s>::const_iterator ' | |
507 'it = %sbegin();' | |
508 % (self._type_helper.GetCppType(item_type), vardot)) | |
509 .Sblock(' it != %send(); ++it) {' % vardot) | |
510 .Append('%s.push_back(%sToString(*it));' % (enum_list_var, | |
511 maybe_namespace)) | |
512 .Eblock('}')) | |
513 | |
514 # Because the std::vector above is always created for both required and | |
515 # optional enum arrays, |is_ptr| is set to false and uses the | |
516 # std::vector to create the values. | |
517 (c.Append(code % | |
518 self._GenerateCreateValueFromType(type_, enum_list_var, False)) | |
519 .Eblock('}')) | |
wjywbs
2014/05/16 19:12:23
Because the variable is scoped, the code generated
| |
520 return c | |
521 | |
522 c.Append(code % self._GenerateCreateValueFromType(type_, var, is_ptr)) | |
523 return c | |
524 | |
525 def _GenerateCreateValueFromType(self, type_, var, is_ptr): | |
526 """Generates the statement to create a base::Value given a type. | |
527 | |
528 type_: The type of the values being converted. | |
529 var: The name of the variable. | |
530 is_ptr: Whether |type_| is optional. | |
531 """ | |
485 underlying_type = self._type_helper.FollowRef(type_) | 532 underlying_type = self._type_helper.FollowRef(type_) |
486 if (underlying_type.property_type == PropertyType.CHOICES or | 533 if (underlying_type.property_type == PropertyType.CHOICES or |
487 underlying_type.property_type == PropertyType.OBJECT): | 534 underlying_type.property_type == PropertyType.OBJECT): |
488 if is_ptr: | 535 if is_ptr: |
489 return '(%s)->ToValue().release()' % var | 536 return '(%s)->ToValue().release()' % var |
490 else: | 537 else: |
491 return '(%s).ToValue().release()' % var | 538 return '(%s).ToValue().release()' % var |
492 elif (underlying_type.property_type == PropertyType.ANY or | 539 elif (underlying_type.property_type == PropertyType.ANY or |
493 underlying_type.property_type == PropertyType.FUNCTION): | 540 underlying_type.property_type == PropertyType.FUNCTION): |
494 if is_ptr: | 541 if is_ptr: |
495 vardot = '(%s)->' % var | 542 vardot = '(%s)->' % var |
496 else: | 543 else: |
497 vardot = '(%s).' % var | 544 vardot = '(%s).' % var |
498 return '%sDeepCopy()' % vardot | 545 return '%sDeepCopy()' % vardot |
499 elif underlying_type.property_type == PropertyType.ENUM: | 546 elif underlying_type.property_type == PropertyType.ENUM: |
500 classname = cpp_util.Classname(schema_util.StripNamespace( | 547 classname = cpp_util.Classname(schema_util.StripNamespace( |
501 underlying_type.name)) | 548 underlying_type.name)) |
502 return 'new base::StringValue(%sToString(%s))' % (classname, var) | 549 return 'new base::StringValue(%sToString(%s))' % (classname, var) |
503 elif underlying_type.property_type == PropertyType.BINARY: | 550 elif underlying_type.property_type == PropertyType.BINARY: |
504 if is_ptr: | 551 if is_ptr: |
505 vardot = var + '->' | 552 vardot = var + '->' |
506 else: | 553 else: |
507 vardot = var + '.' | 554 vardot = var + '.' |
508 return ('base::BinaryValue::CreateWithCopiedBuffer(%sdata(), %ssize())' % | 555 return ('base::BinaryValue::CreateWithCopiedBuffer(%sdata(), %ssize())' % |
509 (vardot, vardot)) | 556 (vardot, vardot)) |
510 elif underlying_type.property_type == PropertyType.ARRAY: | 557 elif underlying_type.property_type == PropertyType.ARRAY: |
511 return '%s.release()' % self._util_cc_helper.CreateValueFromArray( | 558 return '%s.release()' % self._util_cc_helper.CreateValueFromArray( |
512 cpp_namespace, | |
513 underlying_type, | |
514 var, | 559 var, |
515 is_ptr) | 560 is_ptr) |
516 elif underlying_type.property_type.is_fundamental: | 561 elif underlying_type.property_type.is_fundamental: |
517 if is_ptr: | 562 if is_ptr: |
518 var = '*%s' % var | 563 var = '*%s' % var |
519 if underlying_type.property_type == PropertyType.STRING: | 564 if underlying_type.property_type == PropertyType.STRING: |
520 return 'new base::StringValue(%s)' % var | 565 return 'new base::StringValue(%s)' % var |
521 else: | 566 else: |
522 return 'new base::FundamentalValue(%s)' % var | 567 return 'new base::FundamentalValue(%s)' % var |
523 else: | 568 else: |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
954 | 999 |
955 (c.Sblock('scoped_ptr<base::ListValue> %(function_scope)s' | 1000 (c.Sblock('scoped_ptr<base::ListValue> %(function_scope)s' |
956 'Create(%(declaration_list)s) {') | 1001 'Create(%(declaration_list)s) {') |
957 .Append('scoped_ptr<base::ListValue> create_results(' | 1002 .Append('scoped_ptr<base::ListValue> create_results(' |
958 'new base::ListValue());') | 1003 'new base::ListValue());') |
959 ) | 1004 ) |
960 declaration_list = [] | 1005 declaration_list = [] |
961 for param in params: | 1006 for param in params: |
962 declaration_list.append(cpp_util.GetParameterDeclaration( | 1007 declaration_list.append(cpp_util.GetParameterDeclaration( |
963 param, self._type_helper.GetCppType(param.type_))) | 1008 param, self._type_helper.GetCppType(param.type_))) |
964 c.Append('create_results->Append(%s);' % self._CreateValueFromType( | 1009 c.Cblock(self._CreateValueFromType('create_results->Append(%s);', |
965 cpp_namespace, | 1010 param.name, |
966 param.type_, | 1011 param.type_, |
967 param.unix_name)) | 1012 param.unix_name)) |
968 c.Append('return create_results.Pass();') | 1013 c.Append('return create_results.Pass();') |
969 c.Eblock('}') | 1014 c.Eblock('}') |
970 c.Substitute({ | 1015 c.Substitute({ |
971 'function_scope': ('%s::' % function_scope) if function_scope else '', | 1016 'function_scope': ('%s::' % function_scope) if function_scope else '', |
972 'declaration_list': ', '.join(declaration_list), | 1017 'declaration_list': ', '.join(declaration_list), |
973 'param_names': ', '.join(param.unix_name for param in params) | 1018 'param_names': ', '.join(param.unix_name for param in params) |
974 }) | 1019 }) |
975 return c | 1020 return c |
976 | 1021 |
977 def _GenerateEventNameConstant(self, function_scope, event): | 1022 def _GenerateEventNameConstant(self, function_scope, event): |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1018 if self._generate_error_messages: | 1063 if self._generate_error_messages: |
1019 params = list(params) + ['base::string16* error'] | 1064 params = list(params) + ['base::string16* error'] |
1020 return ', '.join(str(p) for p in params) | 1065 return ', '.join(str(p) for p in params) |
1021 | 1066 |
1022 def _GenerateArgs(self, args): | 1067 def _GenerateArgs(self, args): |
1023 """Builds the argument list for a function, given an array of arguments. | 1068 """Builds the argument list for a function, given an array of arguments. |
1024 """ | 1069 """ |
1025 if self._generate_error_messages: | 1070 if self._generate_error_messages: |
1026 args = list(args) + ['error'] | 1071 args = list(args) + ['error'] |
1027 return ', '.join(str(a) for a in args) | 1072 return ', '.join(str(a) for a in args) |
OLD | NEW |