Chromium Code Reviews| 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 code | 6 import code |
| 7 import cpp_util | 7 import cpp_util |
| 8 import util_cc_helper | |
| 8 | 9 |
| 9 class CCGenerator(object): | 10 class CCGenerator(object): |
| 10 """A .cc generator for a namespace. | 11 """A .cc generator for a namespace. |
| 11 """ | 12 """ |
| 12 def __init__(self, namespace, cpp_type_generator): | 13 def __init__(self, namespace, cpp_type_generator): |
| 13 self._cpp_type_generator = cpp_type_generator | 14 self._cpp_type_generator = cpp_type_generator |
| 14 self._namespace = namespace | 15 self._namespace = namespace |
| 15 self._target_namespace = ( | 16 self._target_namespace = ( |
| 16 self._cpp_type_generator.GetCppNamespaceName(self._namespace)) | 17 self._cpp_type_generator.GetCppNamespaceName(self._namespace)) |
| 18 self._util_cc_helper = ( | |
| 19 util_cc_helper.UtilCCHelper(self._cpp_type_generator)) | |
| 17 | 20 |
| 18 def Generate(self): | 21 def Generate(self): |
| 19 """Generates a code.Code object with the .cc for a single namespace. | 22 """Generates a code.Code object with the .cc for a single namespace. |
| 20 """ | 23 """ |
| 21 c = code.Code() | 24 c = code.Code() |
| 22 (c.Append(cpp_util.CHROMIUM_LICENSE) | 25 (c.Append(cpp_util.CHROMIUM_LICENSE) |
| 23 .Append() | 26 .Append() |
| 24 .Append(cpp_util.GENERATED_FILE_MESSAGE % self._namespace.source_file) | 27 .Append(cpp_util.GENERATED_FILE_MESSAGE % self._namespace.source_file) |
| 25 .Append() | 28 .Append() |
| 26 .Append('#include "tools/json_schema_compiler/util.h"') | 29 .Append(self._util_cc_helper.GetIncludePath()) |
| 27 .Append('#include "%s/%s.h"' % | 30 .Append('#include "%s/%s.h"' % |
| 28 (self._namespace.source_file_dir, self._target_namespace)) | 31 (self._namespace.source_file_dir, self._namespace.name)) |
| 29 .Append() | 32 ) |
| 30 .Concat(self._cpp_type_generator.GetCppNamespaceStart()) | 33 includes = self._cpp_type_generator.GenerateIncludes() |
| 34 if not includes.IsEmpty(): | |
| 35 (c.Concat(includes) | |
| 36 .Append() | |
| 37 ) | |
| 38 | |
| 39 (c.Append() | |
| 40 .Concat(self._cpp_type_generator.GetRootNamespaceStart()) | |
| 41 .Concat(self._cpp_type_generator.GetNamespaceStart()) | |
| 31 .Append() | 42 .Append() |
| 32 .Append('//') | 43 .Append('//') |
| 33 .Append('// Types') | 44 .Append('// Types') |
| 34 .Append('//') | 45 .Append('//') |
| 35 .Append() | 46 .Append() |
| 36 ) | 47 ) |
| 37 for type_ in self._namespace.types.values(): | 48 for type_ in self._namespace.types.values(): |
| 38 (c.Concat(self._GenerateType(type_)) | 49 (c.Concat(self._GenerateType(type_.name, type_)) |
| 39 .Append() | 50 .Append() |
| 40 ) | 51 ) |
| 41 (c.Append('//') | 52 (c.Append('//') |
| 42 .Append('// Functions') | 53 .Append('// Functions') |
| 43 .Append('//') | 54 .Append('//') |
| 44 .Append() | 55 .Append() |
| 45 ) | 56 ) |
| 46 for function in self._namespace.functions.values(): | 57 for function in self._namespace.functions.values(): |
| 47 (c.Concat(self._GenerateFunction(function)) | 58 (c.Concat(self._GenerateFunction(function)) |
| 48 .Append() | 59 .Append() |
| 49 ) | 60 ) |
| 50 (c.Concat(self._cpp_type_generator.GetCppNamespaceEnd()) | 61 (c.Concat(self._cpp_type_generator.GetNamespaceEnd()) |
| 62 .Concat(self._cpp_type_generator.GetRootNamespaceEnd()) | |
| 51 .Append() | 63 .Append() |
| 52 ) | 64 ) |
| 53 # TODO(calamity): Events | 65 # TODO(calamity): Events |
| 54 return c | 66 return c |
| 55 | 67 |
| 56 def _GenerateType(self, type_): | 68 def _GenerateType(self, cpp_namespace, type_, serializable=True): |
| 57 """Generates the function definitions for a type. | 69 """Generates the function definitions for a type. |
| 58 """ | 70 """ |
| 71 classname = cpp_util.Classname(type_.name) | |
| 59 c = code.Code() | 72 c = code.Code() |
| 60 | 73 |
| 61 (c.Append('%(classname)s::%(classname)s() {}') | 74 (c.Append('%(namespace)s::%(classname)s() {}') |
| 62 .Append('%(classname)s::~%(classname)s() {}') | 75 .Append('%(namespace)s::~%(classname)s() {}') |
| 63 .Append() | 76 .Append() |
| 64 ) | 77 ) |
| 65 c.Substitute({'classname': type_.name}) | 78 c.Substitute({'classname': classname, 'namespace': cpp_namespace}) |
| 66 | 79 |
| 67 c.Concat(self._GenerateTypePopulate(type_)) | 80 c.Concat(self._GenerateTypePopulate(cpp_namespace, type_)) |
| 68 c.Append() | 81 c.Append() |
| 69 # TODO(calamity): deal with non-serializable | 82 if serializable: |
| 70 c.Concat(self._GenerateTypeTovalue(type_)) | 83 c.Concat(self._GenerateTypeToValue(cpp_namespace, type_)) |
| 71 c.Append() | 84 c.Append() |
| 72 | 85 |
| 73 return c | 86 return c |
| 74 | 87 |
| 75 def _GenerateTypePopulate(self, type_): | 88 def _GenerateTypePopulate(self, cpp_namespace, type_): |
| 76 """Generates the function for populating a type given a pointer to it. | 89 """Generates the function for populating a type given a pointer to it. |
| 77 """ | 90 """ |
| 91 classname = cpp_util.Classname(type_.name) | |
| 78 c = code.Code() | 92 c = code.Code() |
| 79 (c.Append('// static') | 93 (c.Append('// static') |
| 80 .Sblock('bool %(name)s::Populate(const Value& value, %(name)s* out) {') | 94 .Sblock('bool %(namespace)s::Populate' |
| 95 '(const Value& value, %(name)s* out) {') | |
| 81 .Append('if (!value.IsType(Value::TYPE_DICTIONARY))') | 96 .Append('if (!value.IsType(Value::TYPE_DICTIONARY))') |
| 82 .Append(' return false;') | 97 .Append(' return false;') |
| 83 .Append('const DictionaryValue* dict = ' | 98 .Append('const DictionaryValue* dict = ' |
| 84 'static_cast<const DictionaryValue*>(&value);') | 99 'static_cast<const DictionaryValue*>(&value);') |
| 85 .Append() | 100 .Append() |
| 86 ) | 101 ) |
| 87 c.Substitute({'name': type_.name}) | 102 c.Substitute({'namespace': cpp_namespace, 'name': classname}) |
| 88 | 103 |
| 89 # TODO(calamity): this handle single PropertyType.REF properties. | 104 # TODO(calamity): this handle single PropertyType.REF properties. |
| 90 # add ALL the types | 105 # add ALL the types |
| 91 for prop in type_.properties.values(): | 106 for prop in type_.properties.values(): |
| 92 sub = {'name': prop.name} | 107 c.Concat(self._GenerateTypePopulateProperty(prop, 'dict', 'out')) |
| 93 if prop.type_ == PropertyType.ARRAY: | |
| 94 if prop.item_type.type_ == PropertyType.REF: | |
| 95 if prop.optional: | |
| 96 (c.Append('if (!json_schema_compiler::util::' | |
| 97 'GetOptionalTypes<%(type)s>(*dict,') | |
| 98 .Append(' "%(name)s", &out->%(name)s))') | |
| 99 .Append(' return false;') | |
| 100 ) | |
| 101 else: | |
| 102 (c.Append('if (!json_schema_compiler::util::' | |
| 103 'GetTypes<%(type)s>(*dict,') | |
| 104 .Append(' "%(name)s", &out->%(name)s))') | |
| 105 .Append(' return false;') | |
| 106 ) | |
| 107 sub['type'] = self._cpp_type_generator.GetType(prop.item_type, | |
| 108 pad_for_generics=True) | |
| 109 elif prop.item_type.type_ == PropertyType.STRING: | |
| 110 if prop.optional: | |
| 111 (c.Append('if (!json_schema_compiler::util::GetOptionalStrings' | |
| 112 '(*dict, "%(name)s", &out->%(name)s))') | |
| 113 .Append(' return false;') | |
| 114 ) | |
| 115 else: | |
| 116 (c.Append('if (!json_schema_compiler::util::GetStrings' | |
| 117 '(*dict, "%(name)s", &out->%(name)s))') | |
| 118 .Append(' return false;') | |
| 119 ) | |
| 120 else: | |
| 121 raise NotImplementedError(prop.item_type.type_) | |
| 122 elif prop.type_.is_fundamental: | |
| 123 c.Append('if (!dict->%s)' % | |
| 124 cpp_util.GetFundamentalValue(prop, '&out->%s' % prop.name)) | |
| 125 c.Append(' return false;') | |
| 126 else: | |
| 127 raise NotImplementedError(prop.type_) | |
| 128 c.Substitute(sub) | |
| 129 (c.Append('return true;') | 108 (c.Append('return true;') |
| 130 .Eblock('}') | 109 .Eblock('}') |
|
not at google - send to devlin
2012/02/08 05:02:08
indent 2 spaces. I can see why you might have done
calamity
2012/02/08 07:01:18
Done.
| |
| 131 ) | 110 ) |
| 132 return c | 111 return c |
| 133 | 112 |
| 134 def _GenerateTypeTovalue(self, type_): | 113 def _GenerateTypePopulateProperty(self, prop, src, dst): |
|
not at google - send to devlin
2012/02/08 05:02:08
As discussed, most of this code will be replaced w
calamity
2012/02/08 07:01:18
Done.
| |
| 114 """Generate the code to populate a single property. | |
| 115 | |
| 116 src: DictionaryValue* | |
| 117 dst: Type* | |
| 118 """ | |
| 119 c = code.Code() | |
| 120 dst_member = dst + '->' + prop.unix_name | |
| 121 if prop.type_ == PropertyType.ARRAY: | |
| 122 (c.Append('if (!%s)' % | |
| 123 self._util_cc_helper.GetArray(prop, src, prop.name, dst_member)) | |
| 124 .Append(' return false;') | |
| 125 ) | |
| 126 elif prop.type_ == PropertyType.CHOICES: | |
| 127 if prop.optional: | |
| 128 c.Append('%(dst)s_type = %(enum)s::NONE') | |
| 129 for choice in self._cpp_type_generator.ExpandedChoicesInParams([prop]): | |
| 130 dst_member = dst + '->' + choice.unix_name | |
| 131 if choice.type_ == PropertyType.ARRAY: | |
| 132 (c.Append('if (!%s)' % | |
| 133 self._util_cc_helper.GetArray( | |
| 134 choice, src, choice.name,dst_member)) | |
| 135 .Append(' return false;') | |
| 136 ) | |
| 137 else: | |
| 138 (c.Sblock('{') | |
| 139 .Append('%(type)s %(name)s_temp;') | |
| 140 .Append('if (%s) {' % self._GeneratePopulatePropertyFunctionCall( | |
| 141 choice, src, '&%s_temp' % choice.unix_name)) | |
| 142 .Append(' out->%(name)s.reset(new %(type)s(%(name)s_temp));') | |
| 143 .Append(' %(dst)s = %(enum)s;') | |
| 144 .Append('}') | |
| 145 .Eblock('}') | |
| 146 ) | |
| 147 c.Substitute({ | |
| 148 'src': src, | |
| 149 'dst': dst + '->%s_type' % prop.unix_name, | |
| 150 'name': choice.unix_name, | |
| 151 'enum': self._cpp_type_generator.GetChoiceEnum(prop, choice.type_), | |
| 152 'type': self._cpp_type_generator.GetType(choice) | |
| 153 }) | |
| 154 else: | |
| 155 if prop.optional: | |
| 156 if prop.type_.is_fundamental: | |
| 157 (c.Sblock('{') | |
| 158 .Append('%(type)s %(name)s_temp;') | |
| 159 .Append('if (%s)' % self._GeneratePopulatePropertyFunctionCall( | |
| 160 prop, src, '&%s_temp' % prop.unix_name)) | |
| 161 .Append(' out->%(name)s.reset(new %(type)s(%(name)s_temp));') | |
| 162 .Eblock('}') | |
| 163 ) | |
| 164 else: | |
| 165 raise NotImplementedError('Optional %s not implemented' % prop.type_) | |
| 166 else: | |
| 167 (c.Append('if (!%s)' % | |
| 168 self._GeneratePopulatePropertyFunctionCall( | |
| 169 prop, src, '&' + dst_member)) | |
| 170 .Append(' return false;') | |
| 171 ) | |
| 172 c.Substitute({ | |
| 173 'src': src, 'dst': dst_member, 'name': prop.unix_name, | |
| 174 'type': self._cpp_type_generator.GetType(prop) | |
|
not at google - send to devlin
2012/02/08 05:02:08
too much indentation, and spread out each member o
calamity
2012/02/08 07:01:18
Done.
| |
| 175 }) | |
| 176 return c | |
|
not at google - send to devlin
2012/02/08 05:02:08
Can delay substituting src until the end?
c.Subst
calamity
2012/02/08 07:01:18
Done.
not at google - send to devlin
2012/02/09 02:49:36
Not done?
Also you have the same thing above now,
| |
| 177 | |
| 178 def _GeneratePopulatePropertyFunctionCall(self, prop, src, dst): | |
| 179 """Generates the function call that populates the given property. | |
| 180 | |
| 181 src: DictionaryValue* | |
| 182 dst: Property* or scoped_ptr<Property> | |
| 183 """ | |
| 184 if prop.type_.is_fundamental: | |
| 185 populate_line = cpp_util.GetFundamentalValue( | |
| 186 prop, src, prop.name, dst) | |
| 187 elif prop.type_ in (PropertyType.REF, PropertyType.OBJECT): | |
| 188 populate_line = '%(type)s::Populate(*%(src)s, %(dst)s)' | |
| 189 else: | |
| 190 raise NotImplementedError('%s populate is not implemented' % | |
| 191 prop.type_) | |
| 192 return populate_line | |
| 193 | |
| 194 | |
| 195 def _GenerateTypeToValue(self, cpp_namespace, type_): | |
| 135 """Generates a function that serializes the type into a |DictionaryValue|. | 196 """Generates a function that serializes the type into a |DictionaryValue|. |
| 136 """ | 197 """ |
| 137 c = code.Code() | 198 c = code.Code() |
| 138 (c.Sblock('DictionaryValue* %s::ToValue() const {' % type_.name) | 199 (c.Sblock('DictionaryValue* %s::ToValue() const {' % cpp_namespace) |
| 139 .Append('DictionaryValue* value = new DictionaryValue();') | 200 .Append('DictionaryValue* value = new DictionaryValue();') |
| 140 .Append() | 201 .Append() |
| 141 ) | 202 ) |
| 142 name = type_.name.lower() | |
| 143 for prop in type_.properties.values(): | 203 for prop in type_.properties.values(): |
| 144 prop_name = name + '_' + prop.name if name else prop.name | 204 c.Concat(self._CreateValueFromProperty(prop, prop.unix_name, 'value')) |
| 145 this_var = prop.name | |
| 146 c.Concat(self._CreateValueFromProperty(prop_name, prop, this_var)) | |
| 147 (c.Append() | 205 (c.Append() |
| 148 .Append('return value;') | 206 .Append('return value;') |
| 149 .Eblock('}') | 207 .Eblock('}') |
| 150 ) | 208 ) |
| 151 return c | 209 return c |
| 152 | 210 |
| 153 # TODO(calamity): object and choices prop types | 211 def _CreateValueFromProperty(self, prop, var, dst): |
| 154 def _CreateValueFromProperty(self, name, prop, var): | |
| 155 """Generates code to serialize a single property in a type. | 212 """Generates code to serialize a single property in a type. |
| 213 | |
| 214 prop: Property to create from | |
| 215 var: variable with value to create from | |
| 156 """ | 216 """ |
| 157 c = code.Code() | 217 c = code.Code() |
| 158 if prop.type_.is_fundamental: | 218 if prop.optional: |
| 159 c.Append('Value* %s_value = %s;' % | 219 c.Sblock('if (%s.get())' % var) |
| 160 (name, cpp_util.CreateFundamentalValue(prop, var))) | 220 if prop.type_ == PropertyType.ARRAY: |
| 161 elif prop.type_ == PropertyType.ARRAY: | 221 c.Append('%s;' % self._util_cc_helper.SetArray(prop, var, prop.name, dst)) |
| 162 if prop.item_type.type_ == PropertyType.STRING: | |
| 163 if prop.optional: | |
| 164 c.Append('json_schema_compiler::util::' | |
| 165 'SetOptionalStrings(%s, "%s", value);' % (var, prop.name)) | |
| 166 else: | |
| 167 c.Append('json_schema_compiler::util::' | |
| 168 'SetStrings(%s, "%s", value);' % (var, prop.name)) | |
| 169 else: | |
| 170 item_name = name + '_single' | |
| 171 (c.Append('ListValue* %(name)s_value = new ListValue();') | |
| 172 .Append('for (%(it_type)s::iterator it = %(var)s->begin();') | |
| 173 .Sblock(' it != %(var)s->end(); ++it) {') | |
| 174 .Concat(self._CreateValueFromProperty(item_name, prop.item_type, | |
| 175 '*it')) | |
| 176 .Append('%(name)s_value->Append(%(prop_val)s_value);') | |
| 177 .Eblock('}') | |
| 178 ) | |
| 179 c.Substitute( | |
| 180 {'it_type': self._cpp_type_generator.GetType(prop), | |
| 181 'name': name, 'var': var, 'prop_val': item_name}) | |
| 182 elif prop.type_ == PropertyType.REF: | |
| 183 c.Append('Value* %s_value = %s.ToValue();' % (name, var)) | |
| 184 else: | 222 else: |
| 185 raise NotImplementedError | 223 c.Append('%s->SetWithoutPathExpansion("%s", %s);' % |
| 224 (dst, prop.name, cpp_util.CreateValueFromSingleProperty(prop, var))) | |
| 186 return c | 225 return c |
| 187 | 226 |
| 188 def _GenerateFunction(self, function): | 227 def _GenerateFunction(self, function): |
| 189 """Generates the definitions for function structs. | 228 """Generates the definitions for function structs. |
| 190 """ | 229 """ |
| 191 classname = cpp_util.CppName(function.name) | 230 classname = cpp_util.Classname(function.name) |
| 192 c = code.Code() | 231 c = code.Code() |
| 193 | 232 |
| 194 # Params::Populate function | 233 # Params::Populate function |
| 195 if function.params: | 234 if function.params: |
| 235 for param in function.params: | |
| 236 if param.type_ == PropertyType.OBJECT: | |
| 237 param_namespace = '%s::Params::%s' % (classname, | |
| 238 cpp_util.Classname(param.name)) | |
| 239 c.Concat( | |
| 240 self._GenerateType(param_namespace, param, serializable=False)) | |
| 241 c.Append() | |
| 196 (c.Append('%(name)s::Params::Params() {}') | 242 (c.Append('%(name)s::Params::Params() {}') |
| 197 .Append('%(name)s::Params::~Params() {}') | 243 .Append('%(name)s::Params::~Params() {}') |
| 198 .Append() | 244 .Append() |
| 199 .Concat(self._GenerateFunctionParamsCreate(function)) | 245 .Concat(self._GenerateFunctionParamsCreate(function)) |
| 200 .Append() | 246 .Append() |
| 201 ) | 247 ) |
| 202 | 248 |
| 203 # Result::Create function | 249 # Result::Create function |
| 204 c.Concat(self._GenerateFunctionResultCreate(function)) | 250 c.Concat(self._GenerateFunctionResultCreate(function)) |
| 205 | 251 |
| 206 c.Substitute({'name': classname}) | 252 c.Substitute({'name': classname}) |
| 207 | 253 |
| 208 return c | 254 return c |
| 209 | 255 |
| 256 def _GenerateParamsCheck(self, function, var): | |
| 257 """Generates a check for the correct number of arguments when creating Param s. | |
| 258 """ | |
| 259 c = code.Code() | |
| 260 num_optional = 0 | |
| 261 num_required = 0 | |
| 262 for param in function.params: | |
| 263 if param.optional: | |
| 264 num_optional += 1 | |
| 265 else: | |
| 266 num_required += 1 | |
| 267 if num_optional: | |
| 268 (c.Append('if (%(var)s.GetSize() > %(total)d)') | |
| 269 .Append(' return scoped_ptr<Params>();') | |
| 270 ) | |
| 271 if num_required: | |
| 272 (c.Append('if (%(var)s.GetSize() < %(req)d)') | |
| 273 .Append(' return scoped_ptr<Params>();') | |
| 274 ) | |
| 275 c.Substitute({ | |
| 276 'var': var, | |
| 277 'req': num_required, | |
| 278 'total': num_optional + num_required, | |
| 279 }) | |
| 280 return c | |
|
not at google - send to devlin
2012/02/08 05:02:08
y u no write it like I wrote?
I can see why you d
calamity
2012/02/08 07:01:18
Wups, my bad. Note that you can't do args.GetSize(
not at google - send to devlin
2012/02/09 02:49:36
Hah.
| |
| 281 | |
| 210 def _GenerateFunctionParamsCreate(self, function): | 282 def _GenerateFunctionParamsCreate(self, function): |
| 211 """Generate function to create an instance of Params given a pointer. | 283 """Generate function to create an instance of Params given a pointer. |
| 212 """ | 284 """ |
| 213 classname = cpp_util.CppName(function.name) | 285 classname = cpp_util.Classname(function.name) |
| 214 c = code.Code() | 286 c = code.Code() |
| 215 (c.Append('// static') | 287 (c.Append('// static') |
| 216 .Sblock('scoped_ptr<%(classname)s::Params> %(classname)s::Params::Create' | 288 .Sblock('scoped_ptr<%(classname)s::Params> %(classname)s::Params::Create' |
| 217 '(const ListValue& args) {') | 289 '(const ListValue& args) {') |
| 218 .Append('if (args.GetSize() != %d)' % len(function.params)) | 290 .Concat(self._GenerateParamsCheck(function, 'args')) |
| 219 .Append(' return scoped_ptr<Params>();') | |
| 220 .Append() | |
| 221 .Append('scoped_ptr<Params> params(new Params());') | 291 .Append('scoped_ptr<Params> params(new Params());') |
| 222 ) | 292 ) |
| 223 c.Substitute({'classname': classname}) | 293 c.Substitute({'classname': classname}) |
| 224 | 294 |
| 225 # TODO(calamity): generalize, needs to move to function to do populates for | |
| 226 # wider variety of args | |
| 227 for i, param in enumerate(function.params): | 295 for i, param in enumerate(function.params): |
| 228 sub = {'name': param.name, 'pos': i} | 296 dst = 'params->' + param.unix_name |
| 297 if param.optional: | |
| 298 return_line = ' return params.Pass();' | |
| 299 else: | |
| 300 return_line = ' return scoped_ptr<Params>();' | |
| 229 c.Append() | 301 c.Append() |
| 230 # TODO(calamity): Make valid for not just objects | 302 param_var = param.unix_name + '_param' |
| 231 c.Append('DictionaryValue* %(name)s_param = NULL;') | 303 if param.type_ == PropertyType.ARRAY: |
| 232 c.Append('if (!args.GetDictionary(%(pos)d, &%(name)s_param))') | 304 (c.Append('ListValue* %(var)s = NULL;') |
| 233 c.Append(' return scoped_ptr<Params>();') | 305 .Append('if (!args.GetList(%(index)d, &%(var)s))') |
| 234 if param.type_ == PropertyType.REF: | 306 .Append(return_line) |
| 235 c.Append('if (!%(ctype)s::Populate(*%(name)s_param, ' | 307 .Append('if (!%s)' % self._util_cc_helper.GetArrayFromList( |
| 236 '¶ms->%(name)s))') | 308 param, param_var, dst)) |
| 237 c.Append(' return scoped_ptr<Params>();') | 309 .Append(return_line) |
| 238 sub['ctype'] = self._cpp_type_generator.GetType(param) | 310 ) |
| 239 elif param.type_.is_fundamental: | 311 c.Substitute({'var': param_var, 'index': i}) |
| 240 raise NotImplementedError('Fundamental types are unimplemented') | |
| 241 elif param.type_ == PropertyType.OBJECT: | |
| 242 c.Append('if (!%(ctype)s::Populate(*%(name)s_param, ' | |
| 243 '¶ms->%(name)s))') | |
| 244 c.Append(' return scoped_ptr<Params>();') | |
| 245 sub['ctype'] = self._cpp_type_generator.GetType(param) | |
| 246 elif param.type_ == PropertyType.CHOICES: | 312 elif param.type_ == PropertyType.CHOICES: |
| 247 raise NotImplementedError('Choices is unimplemented') | 313 c.Concat(self._GeneratePopulateChoices(param, 'args', i, return_line)) |
| 248 else: | 314 else: |
| 249 raise NotImplementedError(param.type_) | 315 if param.optional: |
| 250 c.Substitute(sub) | 316 dst = dst + '.get()' |
| 251 c.Append() | 317 else: |
| 252 c.Append('return params.Pass();') | 318 dst = '&' + dst |
| 319 if param.type_ in (PropertyType.REF, PropertyType.OBJECT): | |
| 320 (c.Append('DictionaryValue* %s = NULL;' % param_var) | |
| 321 .Append('if (!args.GetDictionary(%d, &%s))' % (i, param_var)) | |
| 322 .Append(return_line) | |
| 323 ) | |
| 324 if param.optional: | |
| 325 c.Append('params->%s.reset(new %s());' % | |
| 326 (param.unix_name, cpp_util.Classname(param.name))) | |
| 327 (c.Append('if (!%(ctype)s::Populate(*%(var)s, %(dst)s))' % { | |
| 328 'var': param_var, 'dst': dst, | |
| 329 'ctype': self._cpp_type_generator.GetType(param) | |
| 330 }) | |
| 331 .Append(return_line) | |
| 332 ) | |
| 333 elif param.type_.is_fundamental: | |
| 334 (c.Append( | |
| 335 'if (!%s)' % cpp_util.GetValueFromList(param, 'args', i, dst)) | |
| 336 .Append(return_line) | |
| 337 ) | |
| 338 (c.Append() | |
| 339 .Append('return params.Pass();') | |
| 340 .Eblock('}') | |
| 341 ) | |
| 342 | |
| 343 return c | |
| 344 | |
| 345 def _GeneratePopulateChoices(self, param, src, index, return_line): | |
|
not at google - send to devlin
2012/02/08 05:02:08
confused by the use of the word "populate" here bu
calamity
2012/02/08 07:01:18
Now it populates. Woo.
| |
| 346 """Generates the code to populate a PropertyType.CHOICES parameter. | |
| 347 | |
| 348 src: ListValue* | |
| 349 index: index of the ListValue the parameter is in | |
| 350 return_line: return line to be used if the choices parameter is not present | |
| 351 """ | |
|
not at google - send to devlin
2012/02/08 05:02:08
as discussed, refactoring to do here.
calamity
2012/02/08 07:01:18
Done.
| |
| 352 c = code.Code() | |
| 353 type_var = 'params->%s_type' % param.unix_name | |
| 354 if param.optional: | |
| 355 type_var = '*' + type_var | |
| 356 c.Append('%s = %s;' % | |
| 357 (type_var, self._cpp_type_generator.GetChoiceEnum(param, None))) | |
| 358 value_var = param.unix_name + '_value' | |
|
not at google - send to devlin
2012/02/08 05:02:08
Refactoring being making this method accept the na
calamity
2012/02/08 07:01:18
Done.
| |
| 359 c.Append('Value* %(value)s = NULL;') | |
| 360 c.Append('if (!%(src)s.Get(%(index)s, &%(value)s))') | |
| 361 c.Append(return_line) | |
|
not at google - send to devlin
2012/02/08 05:02:08
This means that optional parameters can only appea
calamity
2012/02/08 07:01:18
Couldn't figure a case where requires args happen
| |
| 362 c.Sblock('switch (%(value)s->GetType()) {') | |
| 363 c.Substitute({'src': src, 'index': index, 'value': value_var}) | |
|
not at google - send to devlin
2012/02/08 05:02:08
IMO try to put substitutions at the end of these c
calamity
2012/02/08 07:01:18
Done. I'm wary of someone else changing a value in
| |
| 364 for choice in self._cpp_type_generator.ExpandedChoicesInParams([param]): | |
| 365 if choice.type_.is_fundamental: | |
| 366 c.Sblock('case %s: {' % { | |
| 367 PropertyType.STRING: 'Value::TYPE_STRING', | |
| 368 PropertyType.INTEGER: 'Value::TYPE_INTEGER', | |
| 369 PropertyType.BOOLEAN: 'Value::TYPE_BOOLEAN', | |
| 370 PropertyType.DOUBLE: 'Value::TYPE_DOUBLE' | |
| 371 }[choice.type_]) | |
| 372 | |
| 373 dst = 'params->%s.get()' % choice.unix_name | |
| 374 (c.Append(' %(type)s = %(enum)s;') | |
|
not at google - send to devlin
2012/02/08 05:02:08
why the extra spaces before %(type)s?
calamity
2012/02/08 07:01:18
Done.
| |
| 375 .Append('%s;' % | |
| 376 cpp_util.GetAsFundamentalValue(choice, value_var, dst)) | |
| 377 .Append('break;') | |
| 378 .Eblock('}') | |
| 379 ) | |
| 380 elif choice.type_ == PropertyType.ARRAY: | |
| 381 dst = 'params->%s' % choice.unix_name | |
| 382 (c.Sblock('case Value::TYPE_LIST: {') | |
| 383 .Append('%(type)s = %(enum)s;') | |
| 384 .Append('if (!%s)' % self._util_cc_helper.GetArrayFromList( | |
| 385 choice, 'static_cast<ListValue*>(%s)' % value_var, dst)) | |
| 386 .Append(' return scoped_ptr<Params>();') | |
| 387 .Append('break;') | |
| 388 .Eblock('}') | |
| 389 ) | |
| 390 else: | |
| 391 raise NotImplementedError(choice.type_) | |
| 392 c.Substitute({'type': type_var, | |
| 393 'enum': self._cpp_type_generator.GetChoiceEnum(param, choice.type_)}) | |
|
not at google - send to devlin
2012/02/08 05:02:08
I don't know whether enum refers to the type or th
calamity
2012/02/08 07:01:18
Done.
| |
| 394 if not param.optional: | |
| 395 (c.Append('default:') | |
| 396 .Append(' return scoped_ptr<Params>();') | |
| 397 ) | |
| 253 c.Eblock('}') | 398 c.Eblock('}') |
| 254 | |
| 255 return c | 399 return c |
| 256 | 400 |
| 257 def _GenerateFunctionResultCreate(self, function): | 401 def _GenerateFunctionResultCreate(self, function): |
| 258 """Generate function to create a Result given the return value. | 402 """Generate function to create a Result given the return value. |
| 259 """ | 403 """ |
| 260 classname = cpp_util.CppName(function.name) | 404 classname = cpp_util.Classname(function.name) |
| 261 c = code.Code() | 405 c = code.Code() |
| 262 c.Append('// static') | 406 c.Append('// static') |
| 263 param = function.callback.param | 407 params = function.callback.params |
| 264 arg = '' | 408 |
| 265 if param: | 409 if not params: |
| 266 if param.type_ == PropertyType.REF: | 410 (c.Append('Value* %s::Result::Create() {' % classname) |
| 267 arg = 'const %(type)s& %(name)s' | 411 .Append(' return Value::CreateNullValue();') |
| 268 else: | 412 .Append('}') |
| 269 arg = 'const %(type)s %(name)s' | 413 ) |
| 270 arg = arg % { | |
| 271 'type': self._cpp_type_generator.GetType(param), | |
| 272 'name': param.name | |
| 273 } | |
| 274 c.Sblock('Value* %(classname)s::Result::Create(%(arg)s) {') | |
| 275 sub = {'classname': classname, 'arg': arg} | |
| 276 # TODO(calamity): Choices | |
| 277 if not param: | |
| 278 c.Append('return Value::CreateNullValue();') | |
| 279 else: | 414 else: |
| 280 sub['argname'] = param.name | 415 # If there is a single parameter, this is straightforward. However, if |
| 281 if param.type_.is_fundamental: | 416 # the callback parameter is of 'choices', this generates a Create method |
| 282 c.Append('return %s;' % | 417 # for each choice. This works because only 1 choice can be returned at a |
| 283 cpp_util.CreateFundamentalValue(param, param.name)) | 418 # time. |
| 284 elif param.type_ == PropertyType.REF: | 419 for param in self._cpp_type_generator.ExpandedChoicesInParams(params): |
| 285 c.Append('return %(argname)s.ToValue();') | 420 if param.type_ == PropertyType.REF: |
| 286 elif param.type_ == PropertyType.OBJECT: | 421 arg = 'const %(type)s& %(name)s' |
| 287 raise NotImplementedError('Objects not implemented') | 422 else: |
| 288 elif param.type_ == PropertyType.ARRAY: | 423 arg = 'const %(type)s %(name)s' |
| 289 raise NotImplementedError('Arrays not implemented') | 424 arg %= { |
| 290 else: | 425 'type': self._cpp_type_generator.GetType(param, wrap_optional=True), |
| 291 raise NotImplementedError(param.type_) | 426 'name': param.unix_name, |
| 292 c.Substitute(sub) | 427 } |
| 293 c.Eblock('}') | 428 if param and param.description: |
| 429 c.Comment(param.description) | |
| 430 c.Sblock('Value* %(classname)s::Result::Create(%(arg)s) {') | |
| 431 if param.type_ == PropertyType.ARRAY: | |
| 432 (c.Append('ListValue* value = new ListValue();') | |
| 433 .Append('%s;' % self._util_cc_helper.SetArrayToList(param, | |
| 434 param.unix_name, 'value')) | |
| 435 .Append('return value;') | |
| 436 ) | |
| 437 else: | |
| 438 c.Append('return %s;' % cpp_util.CreateValueFromSingleProperty(param, | |
| 439 param.unix_name)) | |
| 440 c.Substitute({'classname': classname, 'arg': arg}) | |
| 441 c.Eblock('}') | |
| 442 | |
| 294 return c | 443 return c |
| OLD | NEW |