Chromium Code Reviews| Index: tools/json_schema_compiler/cc_generator.py |
| diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py |
| index f01479a2f612bb6c41b48a785a9de8898224ced0..d9e6e93a28f932730be94e9a65fdcb001a91e090 100644 |
| --- a/tools/json_schema_compiler/cc_generator.py |
| +++ b/tools/json_schema_compiler/cc_generator.py |
| @@ -109,27 +109,27 @@ class CCGenerator(object): |
| self._GenerateFunction( |
| cpp_namespace + '::' + cpp_util.Classname(function.name), |
| function)) |
| - .Append() |
| - ) |
| + .Append()) |
| elif type_.type_ == PropertyType.OBJECT: |
| (c.Concat(self._GeneratePropertyFunctions( |
| cpp_namespace, type_.properties.values())) |
| .Sblock('%(namespace)s::%(classname)s()') |
| .Concat(self._GenerateInitializersAndBody(type_)) |
| .Eblock('%(namespace)s::~%(classname)s() {}') |
| - .Append() |
| - ) |
| + .Append()) |
| if type_.from_json: |
| (c.Concat(self._GenerateTypePopulate(cpp_namespace, type_)) |
| - .Append() |
| - ) |
| + .Append()) |
| if type_.from_client: |
| (c.Concat(self._GenerateTypeToValue(cpp_namespace, type_)) |
| - .Append() |
| - ) |
| + .Append()) |
| elif self._cpp_type_generator.IsEnumOrEnumRef(type_): |
| - c.Concat(self._GenerateCreateEnumTypeValue(cpp_namespace, type_)) |
| - c.Append() |
| + (c.Concat(self._GenerateCreateEnumTypeValue(cpp_namespace, type_)) |
| + .Append() |
| + .Concat(self._GenerateEnumFromString(cpp_namespace, type_)) |
| + .Append() |
| + .Concat(self._GenerateEnumToString(cpp_namespace, type_)) |
| + .Append()) |
| c.Substitute({'classname': classname, 'namespace': cpp_namespace}) |
| return c |
| @@ -220,12 +220,14 @@ class CCGenerator(object): |
| c.Append('const base::Value* %(value_var)s = NULL;') |
| if prop.optional: |
| (c.Sblock( |
| - 'if (%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s)) {' |
| - ) |
| + 'if (%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s)) {') |
| .Concat(self._GeneratePopulatePropertyFromValue( |
| - prop, value_var, dst, 'false')) |
| - .Eblock('}') |
| - ) |
| + prop, value_var, dst, 'false'))) |
| + if self._cpp_type_generator.IsEnumOrEnumRef(prop): |
| + (c.Append('} else {') |
| + .Append('%%(dst)s->%%(name)s = %s;' % |
| + self._cpp_type_generator.GetEnumNoneValue(prop))) |
| + c.Eblock('}') |
| else: |
| (c.Append( |
| 'if (!%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s))') |
| @@ -234,7 +236,13 @@ class CCGenerator(object): |
| prop, value_var, dst, 'false')) |
| ) |
| c.Append() |
| - c.Substitute({'value_var': value_var, 'key': prop.name, 'src': src}) |
| + c.Substitute({ |
| + 'value_var': value_var, |
| + 'key': prop.name, |
| + 'src': src, |
| + 'dst': dst, |
| + 'name': prop.unix_name |
| + }) |
| return c |
| def _GenerateTypeToValue(self, cpp_namespace, type_): |
| @@ -343,7 +351,7 @@ class CCGenerator(object): |
| vardot = var + '.' |
| return '%sDeepCopy()' % vardot |
| elif self._cpp_type_generator.IsEnumOrEnumRef(prop): |
| - return 'CreateEnumValue(%s).release()' % var |
| + return 'base::Value::CreateStringValue(ToString(%s))' % var |
| elif prop.type_ == PropertyType.BINARY: |
| if prop.optional: |
| vardot = var + '->' |
| @@ -648,11 +656,7 @@ class CCGenerator(object): |
| c.Append('%(dst)s->%(name)s' + accessor + 'push_back(enum_temp);') |
| c.Eblock('}') |
| - def _GenerateStringToEnumConversion(self, |
| - c, |
| - prop, |
| - value_var, |
| - enum_temp): |
| + def _GenerateStringToEnumConversion(self, c, prop, value_var, enum_temp): |
| """Appends code that converts a string to an enum. |
| Leaves failure_value unsubstituted. |
| @@ -661,23 +665,16 @@ class CCGenerator(object): |
| value_var: the string value that is being converted. |
| enum_temp: the name used to store the temporary enum value. |
| """ |
| - (c.Append('%s %s;' % (self._cpp_type_generator.GetCompiledType(prop), |
| - enum_temp)) |
| - .Append('std::string enum_as_string;') |
| + (c.Append('std::string enum_as_string;') |
| .Append('if (!%s->GetAsString(&enum_as_string))' % value_var) |
| .Append(' return %(failure_value)s;') |
| - ) |
| - for i, enum_value in enumerate( |
| - self._cpp_type_generator.GetReferencedProperty(prop).enum_values): |
| - (c.Append( |
| - ('if' if i == 0 else 'else if') + |
| - '(enum_as_string == "%s")' % enum_value) |
| - .Append(' ' + enum_temp + ' = %s;' % ( |
| - self._cpp_type_generator.GetEnumValue(prop, enum_value))) |
| - ) |
| - (c.Append('else') |
| - .Append(' return %(failure_value)s;') |
| - ) |
| + .Append('%s %s = From%sString(enum_as_string);' % |
| + (self._cpp_type_generator.GetCompiledType(prop), |
| + enum_temp, |
| + self._cpp_type_generator.GetCompiledType(prop))) |
|
not at google - send to devlin
2012/09/18 03:55:20
use %s(tring) replacements so that you don't need
cduvall
2012/09/21 00:39:28
Done.
|
| + .Append('if (%s == %s)' % |
| + (enum_temp, self._cpp_type_generator.GetEnumNoneValue(prop))) |
| + .Append(' return %(failure_value)s;')) |
| def _GeneratePropertyFunctions(self, param_namespace, params): |
| """Generate the functions for structures generated by a property such as |
| @@ -699,8 +696,16 @@ class CCGenerator(object): |
| if param.from_client: |
| c.Concat(self._GenerateGetChoiceValue(param_namespace, param)) |
| elif param.type_ == PropertyType.ENUM: |
| - c.Concat(self._GenerateCreateEnumValue(param_namespace, param)) |
| - c.Append() |
| + (c.Concat(self._GenerateCreateEnumValue(param_namespace, param)) |
| + .Append() |
| + .Concat(self._GenerateEnumFromString(param_namespace, |
| + param, |
| + use_namespace=True)) |
| + .Append() |
| + .Concat(self._GenerateEnumToString(param_namespace, |
| + param, |
| + use_namespace=True)) |
| + .Append()) |
| return c |
| def _GenerateGetChoiceValue(self, cpp_namespace, prop): |
| @@ -711,18 +716,15 @@ class CCGenerator(object): |
| (c.Sblock('scoped_ptr<base::Value> ' |
| '%(cpp_namespace)s::Get%(choice)sChoiceValue() const {') |
| .Sblock('switch (%s_type) {' % prop.unix_name) |
| - ) |
| - if prop.optional: |
| - c.Concat(self._GenerateReturnCase( |
| + .Concat(self._GenerateReturnCase( |
| self._cpp_type_generator.GetEnumNoneValue(prop), |
| - 'scoped_ptr<base::Value>()')) |
| + 'scoped_ptr<base::Value>()'))) |
| for choice in self._cpp_type_generator.ExpandParams([prop]): |
| c.Concat(self._GenerateReturnCase( |
| self._cpp_type_generator.GetEnumValue(prop, choice.type_.name), |
| 'make_scoped_ptr<base::Value>(%s)' % |
| self._CreateValueFromProperty(choice, choice.unix_name))) |
| (c.Eblock('}') |
| - .Append('NOTREACHED();') |
| .Append('return scoped_ptr<base::Value>();') |
| .Eblock('}') |
| .Append() |
| @@ -746,14 +748,74 @@ class CCGenerator(object): |
| enum_prop = self._cpp_type_generator.GetReferencedProperty(prop) |
| for enum_value in enum_prop.enum_values: |
| c.Concat(self._GenerateReturnCase( |
| - '%s_%s' % (classname.upper(), enum_value.upper()), |
| + '%s' % self._cpp_type_generator.GetEnumValue(prop, enum_value), |
| 'scoped_ptr<base::Value>(base::Value::CreateStringValue("%s"))' % |
| enum_value)) |
| - (c.Eblock('}') |
| - .Append('NOTREACHED();') |
| + (c.Append('case %s:' % self._cpp_type_generator.GetEnumNoneValue(prop)) |
| + .Append(' return scoped_ptr<base::Value>();') |
| + .Eblock('}') |
| .Append('return scoped_ptr<base::Value>();') |
| + .Eblock('}')) |
| + return c |
| + |
| + def _GenerateEnumToString(self, cpp_namespace, prop, use_namespace=False): |
| + """Generates ToString() which gets the string representation of an enum. |
| + """ |
| + c = Code() |
| + classname = cpp_util.Classname(schema_util.StripSchemaNamespace(prop.name)) |
| + if use_namespace: |
| + namespace = '%s::' % cpp_namespace |
| + else: |
| + namespace = '' |
| + |
| + (c.Append('// static') |
| + .Sblock('std::string %(namespace)sToString(%(class)s enum_param) {') |
| + .Append('std::string temp_string;') |
| + .Append('scoped_ptr<base::Value> enum_value(' |
| + 'CreateEnumValue(enum_param));') |
| + .Append('if (!enum_value.get())') |
| + .Append(' return "";') |
| + .Append('if (!enum_value->GetAsString(&temp_string))') |
|
not at google - send to devlin
2012/09/18 03:55:20
Pulling the string out of the value here seems rou
cduvall
2012/09/21 00:39:28
Done.
|
| + .Append(' return "";') |
| + .Append('return temp_string;') |
| .Eblock('}') |
| - ) |
| + .Substitute({ |
| + 'namespace': namespace, |
| + 'class': classname |
| + })) |
| + return c |
| + |
| + def _GenerateEnumFromString(self, cpp_namespace, prop, use_namespace=False): |
| + """Generates FromClassNameString() which gets an enum from its string |
| + representation. |
| + """ |
| + c = Code() |
| + classname = cpp_util.Classname(schema_util.StripSchemaNamespace(prop.name)) |
| + if use_namespace: |
| + namespace = '%s::' % cpp_namespace |
| + else: |
| + namespace = '' |
| + |
| + (c.Append('// static') |
| + .Sblock('%(namespace)s%(class)s' |
| + ' %(namespace)sFrom%(class)sString(' |
| + 'const std::string& enum_string) {')) |
| + enum_prop = self._cpp_type_generator.GetReferencedProperty(prop) |
| + for i, enum_value in enumerate( |
| + self._cpp_type_generator.GetReferencedProperty(prop).enum_values): |
| + # This is broken up into all ifs with no else ifs because we get |
| + # "fatal error C1061: compiler limit : blocks nested too deeply" |
| + # on Windows. |
| + (c.Append('if (enum_string == "%s")' % enum_value) |
| + .Append(' return %s;' % |
| + self._cpp_type_generator.GetEnumValue(prop, enum_value))) |
| + (c.Append('return %s;' % |
| + self._cpp_type_generator.GetEnumNoneValue(prop)) |
| + .Eblock('}') |
| + .Substitute({ |
| + 'namespace': namespace, |
| + 'class': classname |
| + })) |
| return c |
| # TODO(chebert): This is basically the same as GenerateCreateEnumTypeValue(). |
| @@ -764,29 +826,26 @@ class CCGenerator(object): |
| representation of an enum. |
| """ |
| c = Code() |
| - c.Append('// static') |
| - c.Sblock('scoped_ptr<base::Value> %(cpp_namespace)s::CreateEnumValue(' |
| + (c.Append('// static') |
| + .Sblock('scoped_ptr<base::Value> %(cpp_namespace)s::CreateEnumValue(' |
| '%(arg)s) {') |
| - c.Sblock('switch (%s) {' % prop.unix_name) |
| - if prop.optional: |
| - c.Concat(self._GenerateReturnCase( |
| - self._cpp_type_generator.GetEnumNoneValue(prop), |
| - 'scoped_ptr<base::Value>()')) |
| + .Sblock('switch (%s) {' % prop.unix_name) |
| + .Concat(self._GenerateReturnCase( |
| + self._cpp_type_generator.GetEnumNoneValue(prop), |
| + 'scoped_ptr<base::Value>()'))) |
| for enum_value in prop.enum_values: |
| c.Concat(self._GenerateReturnCase( |
| self._cpp_type_generator.GetEnumValue(prop, enum_value), |
|
not at google - send to devlin
2012/09/18 03:55:20
can you make this method just call FromString? it
cduvall
2012/09/21 00:39:28
Done, assuming you meant ToString.
|
| 'scoped_ptr<base::Value>(base::Value::CreateStringValue("%s"))' % |
| enum_value)) |
| (c.Eblock('}') |
| - .Append('NOTREACHED();') |
| .Append('return scoped_ptr<base::Value>();') |
| .Eblock('}') |
| .Substitute({ |
| 'cpp_namespace': cpp_namespace, |
| 'arg': cpp_util.GetParameterDeclaration( |
| prop, self._cpp_type_generator.GetType(prop)) |
| - }) |
| - ) |
| + })) |
| return c |
| def _GenerateReturnCase(self, case_value, return_value): |