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 any_helper | 7 import any_helper |
8 import cpp_util | 8 import cpp_util |
9 import model | 9 import model |
10 import schema_util | 10 import schema_util |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
123 (c.Concat(self._GenerateTypePopulate(cpp_namespace, type_)) | 123 (c.Concat(self._GenerateTypePopulate(cpp_namespace, type_)) |
124 .Append() | 124 .Append() |
125 ) | 125 ) |
126 if type_.from_client: | 126 if type_.from_client: |
127 (c.Concat(self._GenerateTypeToValue(cpp_namespace, type_)) | 127 (c.Concat(self._GenerateTypeToValue(cpp_namespace, type_)) |
128 .Append() | 128 .Append() |
129 ) | 129 ) |
130 elif self._cpp_type_generator.IsEnumOrEnumRef(type_): | 130 elif self._cpp_type_generator.IsEnumOrEnumRef(type_): |
131 c.Concat(self._GenerateCreateEnumTypeValue(cpp_namespace, type_)) | 131 c.Concat(self._GenerateCreateEnumTypeValue(cpp_namespace, type_)) |
132 c.Append() | 132 c.Append() |
133 c.Concat(self._GenerateGetEnumTypeFromString(cpp_namespace, type_)) | |
134 c.Append() | |
not at google - send to devlin
2012/09/14 01:44:51
nit: style like
(c.Concat(...)
.Append()
.Con
cduvall
2012/09/17 22:07:46
Done.
| |
133 c.Substitute({'classname': classname, 'namespace': cpp_namespace}) | 135 c.Substitute({'classname': classname, 'namespace': cpp_namespace}) |
134 | 136 |
135 return c | 137 return c |
136 | 138 |
137 def _GenerateInitializersAndBody(self, type_): | 139 def _GenerateInitializersAndBody(self, type_): |
138 items = [] | 140 items = [] |
139 for prop in type_.properties.values(): | 141 for prop in type_.properties.values(): |
140 if prop.optional: | 142 if prop.optional: |
141 continue | 143 continue |
142 | 144 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
213 """Generate the code to populate a single property in a type. | 215 """Generate the code to populate a single property in a type. |
214 | 216 |
215 src: base::DictionaryValue* | 217 src: base::DictionaryValue* |
216 dst: Type* | 218 dst: Type* |
217 """ | 219 """ |
218 c = Code() | 220 c = Code() |
219 value_var = prop.unix_name + '_value' | 221 value_var = prop.unix_name + '_value' |
220 c.Append('const base::Value* %(value_var)s = NULL;') | 222 c.Append('const base::Value* %(value_var)s = NULL;') |
221 if prop.optional: | 223 if prop.optional: |
222 (c.Sblock( | 224 (c.Sblock( |
223 'if (%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s)) {' | 225 'if (%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s)) {') |
224 ) | |
225 .Concat(self._GeneratePopulatePropertyFromValue( | 226 .Concat(self._GeneratePopulatePropertyFromValue( |
226 prop, value_var, dst, 'false')) | 227 prop, value_var, dst, 'false')) |
227 .Eblock('}') | 228 .Eblock('}')) |
228 ) | 229 if self._cpp_type_generator.IsEnumOrEnumRef(prop): |
230 (c.Sblock('else {') | |
not at google - send to devlin
2012/09/14 01:44:51
would be nice to generate style-guide compatible c
cduvall
2012/09/17 22:07:46
Done.
| |
231 .Append('%%(dst)s->%%(name)s = %s;' % | |
232 self._cpp_type_generator.GetEnumNoneValue(prop)) | |
233 .Eblock('}')) | |
229 else: | 234 else: |
230 (c.Append( | 235 (c.Append( |
231 'if (!%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s))') | 236 'if (!%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s))') |
232 .Append(' return false;') | 237 .Append(' return false;') |
233 .Concat(self._GeneratePopulatePropertyFromValue( | 238 .Concat(self._GeneratePopulatePropertyFromValue( |
234 prop, value_var, dst, 'false')) | 239 prop, value_var, dst, 'false')) |
235 ) | 240 ) |
236 c.Append() | 241 c.Append() |
237 c.Substitute({'value_var': value_var, 'key': prop.name, 'src': src}) | 242 c.Substitute({ |
243 'value_var': value_var, | |
244 'key': prop.name, | |
245 'src': src, | |
246 'dst': dst, | |
247 'name': prop.unix_name | |
248 }) | |
238 return c | 249 return c |
239 | 250 |
240 def _GenerateTypeToValue(self, cpp_namespace, type_): | 251 def _GenerateTypeToValue(self, cpp_namespace, type_): |
241 """Generates a function that serializes the type into a | 252 """Generates a function that serializes the type into a |
242 |base::DictionaryValue|. | 253 |base::DictionaryValue|. |
243 | 254 |
244 E.g. for type "Foo" generates Foo::ToValue() | 255 E.g. for type "Foo" generates Foo::ToValue() |
245 """ | 256 """ |
246 c = Code() | 257 c = Code() |
247 (c.Sblock('scoped_ptr<base::DictionaryValue> %s::ToValue() const {' % | 258 (c.Sblock('scoped_ptr<base::DictionaryValue> %s::ToValue() const {' % |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
641 c.Append('%(dst)s->%(name)s.reset(new std::vector<' + ( | 652 c.Append('%(dst)s->%(name)s.reset(new std::vector<' + ( |
642 self._cpp_type_generator.GetType(prop.item_type) + '>);')) | 653 self._cpp_type_generator.GetType(prop.item_type) + '>);')) |
643 accessor = '->' | 654 accessor = '->' |
644 c.Sblock('for (ListValue::const_iterator it = list->begin(); ' | 655 c.Sblock('for (ListValue::const_iterator it = list->begin(); ' |
645 'it != list->end(); ++it) {') | 656 'it != list->end(); ++it) {') |
646 self._GenerateStringToEnumConversion( | 657 self._GenerateStringToEnumConversion( |
647 c, prop.item_type, '(*it)', 'enum_temp') | 658 c, prop.item_type, '(*it)', 'enum_temp') |
648 c.Append('%(dst)s->%(name)s' + accessor + 'push_back(enum_temp);') | 659 c.Append('%(dst)s->%(name)s' + accessor + 'push_back(enum_temp);') |
649 c.Eblock('}') | 660 c.Eblock('}') |
650 | 661 |
651 def _GenerateStringToEnumConversion(self, | 662 def _GenerateStringToEnumConversion(self, c, prop, value_var, enum_temp): |
652 c, | |
653 prop, | |
654 value_var, | |
655 enum_temp): | |
656 """Appends code that converts a string to an enum. | 663 """Appends code that converts a string to an enum. |
657 Leaves failure_value unsubstituted. | 664 Leaves failure_value unsubstituted. |
658 | 665 |
659 c: the code that is appended to. | 666 c: the code that is appended to. |
660 prop: the property that the code is populating. | 667 prop: the property that the code is populating. |
661 value_var: the string value that is being converted. | 668 value_var: the string value that is being converted. |
662 enum_temp: the name used to store the temporary enum value. | 669 enum_temp: the name used to store the temporary enum value. |
663 """ | 670 """ |
664 (c.Append('%s %s;' % (self._cpp_type_generator.GetCompiledType(prop), | 671 c.Append('%s %s = %s;' % (self._cpp_type_generator.GetCompiledType(prop), |
665 enum_temp)) | 672 enum_temp, |
666 .Append('std::string enum_as_string;') | 673 self._cpp_type_generator.GetEnumNoneValue(prop))) |
674 (c.Append('std::string enum_as_string;') | |
667 .Append('if (!%s->GetAsString(&enum_as_string))' % value_var) | 675 .Append('if (!%s->GetAsString(&enum_as_string))' % value_var) |
668 .Append(' return %(failure_value)s;') | 676 .Append(' return %(failure_value)s;')) |
669 ) | |
670 for i, enum_value in enumerate( | 677 for i, enum_value in enumerate( |
671 self._cpp_type_generator.GetReferencedProperty(prop).enum_values): | 678 self._cpp_type_generator.GetReferencedProperty(prop).enum_values): |
672 (c.Append( | 679 (c.Append('if (enum_as_string == "%s")' % enum_value) |
673 ('if' if i == 0 else 'else if') + | 680 .Append(' %s = %s;' % |
674 '(enum_as_string == "%s")' % enum_value) | 681 (enum_temp, |
675 .Append(' ' + enum_temp + ' = %s;' % ( | 682 self._cpp_type_generator.GetEnumValue(prop, enum_value)))) |
676 self._cpp_type_generator.GetEnumValue(prop, enum_value))) | 683 (c.Append('if (%s == %s)' % |
677 ) | 684 (enum_temp, self._cpp_type_generator.GetEnumNoneValue(prop))) |
678 (c.Append('else') | 685 .Append(' return %(failure_value)s;')) |
679 .Append(' return %(failure_value)s;') | |
680 ) | |
681 | 686 |
682 def _GeneratePropertyFunctions(self, param_namespace, params): | 687 def _GeneratePropertyFunctions(self, param_namespace, params): |
683 """Generate the functions for structures generated by a property such as | 688 """Generate the functions for structures generated by a property such as |
684 CreateEnumValue for ENUMs and Populate/ToValue for Params/Results objects. | 689 CreateEnumValue for ENUMs and Populate/ToValue for Params/Results objects. |
685 """ | 690 """ |
686 c = Code() | 691 c = Code() |
687 for param in params: | 692 for param in params: |
688 if param.type_ == PropertyType.OBJECT: | 693 if param.type_ == PropertyType.OBJECT: |
689 c.Concat(self._GenerateType( | 694 c.Concat(self._GenerateType( |
690 param_namespace + '::' + cpp_util.Classname(param.name), | 695 param_namespace + '::' + cpp_util.Classname(param.name), |
(...skipping 23 matching lines...) Expand all Loading... | |
714 ) | 719 ) |
715 if prop.optional: | 720 if prop.optional: |
716 c.Concat(self._GenerateReturnCase( | 721 c.Concat(self._GenerateReturnCase( |
717 self._cpp_type_generator.GetEnumNoneValue(prop), | 722 self._cpp_type_generator.GetEnumNoneValue(prop), |
718 'scoped_ptr<base::Value>()')) | 723 'scoped_ptr<base::Value>()')) |
719 for choice in self._cpp_type_generator.ExpandParams([prop]): | 724 for choice in self._cpp_type_generator.ExpandParams([prop]): |
720 c.Concat(self._GenerateReturnCase( | 725 c.Concat(self._GenerateReturnCase( |
721 self._cpp_type_generator.GetEnumValue(prop, choice.type_.name), | 726 self._cpp_type_generator.GetEnumValue(prop, choice.type_.name), |
722 'make_scoped_ptr<base::Value>(%s)' % | 727 'make_scoped_ptr<base::Value>(%s)' % |
723 self._CreateValueFromProperty(choice, choice.unix_name))) | 728 self._CreateValueFromProperty(choice, choice.unix_name))) |
724 (c.Eblock('}') | 729 (c.Append('default:') |
not at google - send to devlin
2012/09/14 01:44:51
so... is this a place where we legitimately don't
cduvall
2012/09/17 22:07:46
Done.
| |
725 .Append('NOTREACHED();') | 730 .Append(' NOTREACHED();') |
726 .Append('return scoped_ptr<base::Value>();') | 731 .Append(' return scoped_ptr<base::Value>();') |
732 .Eblock('}') | |
727 .Eblock('}') | 733 .Eblock('}') |
728 .Append() | 734 .Append() |
729 .Substitute({ | 735 .Substitute({ |
730 'cpp_namespace': cpp_namespace, | 736 'cpp_namespace': cpp_namespace, |
731 'choice': cpp_util.Classname(prop.name) | 737 'choice': cpp_util.Classname(prop.name) |
732 }) | 738 }) |
733 ) | 739 ) |
734 return c | 740 return c |
735 | 741 |
736 def _GenerateCreateEnumTypeValue(self, cpp_namespace, prop): | 742 def _GenerateCreateEnumTypeValue(self, cpp_namespace, prop): |
737 """Generates CreateEnumValue() that returns the base::StringValue | 743 """Generates CreateEnumValue() that returns the base::StringValue |
738 representation of an enum type. | 744 representation of an enum type. |
739 """ | 745 """ |
740 c = Code() | 746 c = Code() |
741 classname = cpp_util.Classname(schema_util.StripSchemaNamespace(prop.name)) | 747 classname = cpp_util.Classname(schema_util.StripSchemaNamespace(prop.name)) |
742 c.Sblock('scoped_ptr<base::Value> CreateEnumValue(%s %s) {' % ( | 748 c.Sblock('scoped_ptr<base::Value> CreateEnumValue(%s %s) {' % ( |
743 classname, classname.lower())) | 749 classname, classname.lower())) |
744 c.Sblock('switch (%s) {' % classname.lower()) | 750 c.Sblock('switch (%s) {' % classname.lower()) |
745 | 751 |
746 enum_prop = self._cpp_type_generator.GetReferencedProperty(prop) | 752 enum_prop = self._cpp_type_generator.GetReferencedProperty(prop) |
747 for enum_value in enum_prop.enum_values: | 753 for enum_value in enum_prop.enum_values: |
748 c.Concat(self._GenerateReturnCase( | 754 c.Concat(self._GenerateReturnCase( |
749 '%s_%s' % (classname.upper(), enum_value.upper()), | 755 '%s_%s' % (classname.upper(), enum_value.upper()), |
750 'scoped_ptr<base::Value>(base::Value::CreateStringValue("%s"))' % | 756 'scoped_ptr<base::Value>(base::Value::CreateStringValue("%s"))' % |
751 enum_value)) | 757 enum_value)) |
752 (c.Eblock('}') | 758 # We need a default case because all enum types have a *_NONE value, which |
753 .Append('NOTREACHED();') | 759 # is not handled in the other cases. |
not at google - send to devlin
2012/09/14 01:44:51
confused, can't you handle the NONE case explicitl
cduvall
2012/09/17 22:07:46
Done.
| |
754 .Append('return scoped_ptr<base::Value>();') | 760 (c.Append('default:') |
761 .Append(' return scoped_ptr<base::Value>();') | |
755 .Eblock('}') | 762 .Eblock('}') |
763 .Eblock('}')) | |
764 return c | |
765 | |
766 def _GenerateGetEnumTypeFromString(self, cpp_namespace, prop): | |
767 """Generates GetEnumFromString() which gets an enum from its string | |
768 representation. | |
769 """ | |
770 c = Code() | |
771 classname = cpp_util.Classname(schema_util.StripSchemaNamespace(prop.name)) | |
772 (c.Append('// static') | |
773 .Sblock('bool GetEnumFromString(const std::string& enum_string,' | |
not at google - send to devlin
2012/09/14 01:44:51
does it make sense to return the enum directly? We
cduvall
2012/09/17 22:07:46
Done.
| |
774 ' %(class)s* %(var)s) {')) | |
not at google - send to devlin
2012/09/14 01:44:51
how about generating a ToString(enum) too? seems u
cduvall
2012/09/17 22:07:46
Done.
| |
775 enum_prop = self._cpp_type_generator.GetReferencedProperty(prop) | |
776 for i, enum_value in enumerate( | |
777 self._cpp_type_generator.GetReferencedProperty(prop).enum_values): | |
778 # This is broken up into all ifs with no else ifs because we get | |
779 # "fatal error C1061: compiler limit : blocks nested too deeply" | |
780 # on Windows. | |
not at google - send to devlin
2012/09/14 01:44:51
haha
| |
781 (c.Sblock('if (enum_string == "%s") {' % enum_value) | |
782 .Append('*%%(var)s = %s_%s;' % (classname.upper(), enum_value.upper())) | |
783 .Append('return true;') | |
784 .Eblock('}')) | |
785 (c.Append('return false;') | |
786 .Eblock('}') | |
787 .Substitute({ | |
788 'cpp_namespace': cpp_namespace, | |
789 'var': classname.lower(), | |
790 'class': classname | |
791 }) | |
756 ) | 792 ) |
757 return c | 793 return c |
758 | 794 |
759 # TODO(chebert): This is basically the same as GenerateCreateEnumTypeValue(). | 795 # TODO(chebert): This is basically the same as GenerateCreateEnumTypeValue(). |
760 # The plan is to phase out the old-style enums, and make all enums into REF | 796 # The plan is to phase out the old-style enums, and make all enums into REF |
761 # types. | 797 # types. |
762 def _GenerateCreateEnumValue(self, cpp_namespace, prop): | 798 def _GenerateCreateEnumValue(self, cpp_namespace, prop): |
763 """Generates CreateEnumValue() that returns the base::StringValue | 799 """Generates CreateEnumValue() that returns the base::StringValue |
764 representation of an enum. | 800 representation of an enum. |
765 """ | 801 """ |
766 c = Code() | 802 c = Code() |
767 c.Append('// static') | 803 c.Append('// static') |
768 c.Sblock('scoped_ptr<base::Value> %(cpp_namespace)s::CreateEnumValue(' | 804 c.Sblock('scoped_ptr<base::Value> %(cpp_namespace)s::CreateEnumValue(' |
769 '%(arg)s) {') | 805 '%(arg)s) {') |
770 c.Sblock('switch (%s) {' % prop.unix_name) | 806 c.Sblock('switch (%s) {' % prop.unix_name) |
771 if prop.optional: | 807 if prop.optional: |
772 c.Concat(self._GenerateReturnCase( | 808 c.Concat(self._GenerateReturnCase( |
773 self._cpp_type_generator.GetEnumNoneValue(prop), | 809 self._cpp_type_generator.GetEnumNoneValue(prop), |
774 'scoped_ptr<base::Value>()')) | 810 'scoped_ptr<base::Value>()')) |
775 for enum_value in prop.enum_values: | 811 for enum_value in prop.enum_values: |
776 c.Concat(self._GenerateReturnCase( | 812 c.Concat(self._GenerateReturnCase( |
777 self._cpp_type_generator.GetEnumValue(prop, enum_value), | 813 self._cpp_type_generator.GetEnumValue(prop, enum_value), |
778 'scoped_ptr<base::Value>(base::Value::CreateStringValue("%s"))' % | 814 'scoped_ptr<base::Value>(base::Value::CreateStringValue("%s"))' % |
779 enum_value)) | 815 enum_value)) |
780 (c.Eblock('}') | 816 (c.Append('default:') |
not at google - send to devlin
2012/09/14 01:44:51
ditto
cduvall
2012/09/17 22:07:46
Done.
| |
781 .Append('NOTREACHED();') | 817 .Append(' NOTREACHED();') |
782 .Append('return scoped_ptr<base::Value>();') | 818 .Append(' return scoped_ptr<base::Value>();') |
819 .Eblock('}') | |
783 .Eblock('}') | 820 .Eblock('}') |
784 .Substitute({ | 821 .Substitute({ |
785 'cpp_namespace': cpp_namespace, | 822 'cpp_namespace': cpp_namespace, |
786 'arg': cpp_util.GetParameterDeclaration( | 823 'arg': cpp_util.GetParameterDeclaration( |
787 prop, self._cpp_type_generator.GetType(prop)) | 824 prop, self._cpp_type_generator.GetType(prop)) |
788 }) | 825 }) |
789 ) | 826 ) |
790 return c | 827 return c |
791 | 828 |
792 def _GenerateReturnCase(self, case_value, return_value): | 829 def _GenerateReturnCase(self, case_value, return_value): |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
898 """ | 935 """ |
899 return (self._cpp_type_generator.GetReferencedProperty(prop).type_ == | 936 return (self._cpp_type_generator.GetReferencedProperty(prop).type_ == |
900 PropertyType.ARRAY) | 937 PropertyType.ARRAY) |
901 | 938 |
902 def _IsFundamentalOrFundamentalRef(self, prop): | 939 def _IsFundamentalOrFundamentalRef(self, prop): |
903 """Determines if this property is a Fundamental type or is a ref to a | 940 """Determines if this property is a Fundamental type or is a ref to a |
904 Fundamental type. | 941 Fundamental type. |
905 """ | 942 """ |
906 return (self._cpp_type_generator.GetReferencedProperty(prop).type_. | 943 return (self._cpp_type_generator.GetReferencedProperty(prop).type_. |
907 is_fundamental) | 944 is_fundamental) |
OLD | NEW |