| 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 import util_cc_helper |
| 9 | 9 |
| 10 class CCGenerator(object): | 10 class CCGenerator(object): |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 ) | 37 ) |
| 38 | 38 |
| 39 (c.Append() | 39 (c.Append() |
| 40 .Append('using base::Value;') | 40 .Append('using base::Value;') |
| 41 .Append('using base::DictionaryValue;') | 41 .Append('using base::DictionaryValue;') |
| 42 .Append('using base::ListValue;') | 42 .Append('using base::ListValue;') |
| 43 .Append() | 43 .Append() |
| 44 .Concat(self._cpp_type_generator.GetRootNamespaceStart()) | 44 .Concat(self._cpp_type_generator.GetRootNamespaceStart()) |
| 45 .Concat(self._cpp_type_generator.GetNamespaceStart()) | 45 .Concat(self._cpp_type_generator.GetNamespaceStart()) |
| 46 .Append() | 46 .Append() |
| 47 .Append('//') | |
| 48 .Append('// Types') | |
| 49 .Append('//') | |
| 50 .Append() | |
| 51 ) | 47 ) |
| 48 if self._namespace.types: |
| 49 (c.Append('//') |
| 50 .Append('// Types') |
| 51 .Append('//') |
| 52 .Append() |
| 53 ) |
| 52 for type_ in self._namespace.types.values(): | 54 for type_ in self._namespace.types.values(): |
| 53 (c.Concat(self._GenerateType(type_.name, type_)) | 55 (c.Concat(self._GenerateType(type_.name, type_)) |
| 54 .Append() | 56 .Append() |
| 55 ) | 57 ) |
| 56 (c.Append('//') | 58 if self._namespace.functions: |
| 57 .Append('// Functions') | 59 (c.Append('//') |
| 58 .Append('//') | 60 .Append('// Functions') |
| 59 .Append() | 61 .Append('//') |
| 60 ) | 62 .Append() |
| 63 ) |
| 61 for function in self._namespace.functions.values(): | 64 for function in self._namespace.functions.values(): |
| 62 (c.Concat(self._GenerateFunction(function)) | 65 (c.Concat(self._GenerateFunction(function)) |
| 63 .Append() | 66 .Append() |
| 64 ) | 67 ) |
| 65 (c.Concat(self._cpp_type_generator.GetNamespaceEnd()) | 68 (c.Concat(self._cpp_type_generator.GetNamespaceEnd()) |
| 66 .Concat(self._cpp_type_generator.GetRootNamespaceEnd()) | 69 .Concat(self._cpp_type_generator.GetRootNamespaceEnd()) |
| 67 .Append() | 70 .Append() |
| 68 ) | 71 ) |
| 69 # TODO(calamity): Events | 72 # TODO(calamity): Events |
| 70 return c | 73 return c |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 ) | 107 ) |
| 105 for prop in type_.properties.values(): | 108 for prop in type_.properties.values(): |
| 106 c.Concat(self._GenerateTypePopulateProperty(prop, 'dict', 'out')) | 109 c.Concat(self._GenerateTypePopulateProperty(prop, 'dict', 'out')) |
| 107 (c.Append('return true;') | 110 (c.Append('return true;') |
| 108 .Eblock('}') | 111 .Eblock('}') |
| 109 ) | 112 ) |
| 110 c.Substitute({'namespace': cpp_namespace, 'name': classname}) | 113 c.Substitute({'namespace': cpp_namespace, 'name': classname}) |
| 111 return c | 114 return c |
| 112 | 115 |
| 113 def _GenerateTypePopulateProperty(self, prop, src, dst): | 116 def _GenerateTypePopulateProperty(self, prop, src, dst): |
| 114 """Generate the code to populate a single property. | 117 """Generate the code to populate a single property in a type. |
| 115 | 118 |
| 116 src: DictionaryValue* | 119 src: DictionaryValue* |
| 117 dst: Type* | 120 dst: Type* |
| 118 """ | 121 """ |
| 119 c = code.Code() | 122 c = code.Code() |
| 120 dst_member = dst + '->' + prop.unix_name | 123 value_var = prop.unix_name + '_value' |
| 121 if prop.type_ == PropertyType.ARRAY: | 124 c.Append('Value* %(value_var)s = NULL;') |
| 122 # util_cc_helper deals with optional and required arrays | 125 if prop.optional: |
| 123 (c.Append('if (!%s)' % | 126 (c.Sblock( |
| 124 self._util_cc_helper.GetArray(prop, src, prop.name, dst_member)) | 127 'if (%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s)) {' |
| 128 ) |
| 129 .Concat(self._GeneratePopulatePropertyFromValue( |
| 130 prop, value_var, 'out', 'false')) |
| 131 .Eblock('}') |
| 132 ) |
| 133 else: |
| 134 (c.Append( |
| 135 'if (!%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s))') |
| 125 .Append(' return false;') | 136 .Append(' return false;') |
| 137 .Concat(self._GeneratePopulatePropertyFromValue( |
| 138 prop, value_var, 'out', 'false')) |
| 126 ) | 139 ) |
| 127 elif prop.type_ == PropertyType.CHOICES: | 140 c.Append() |
| 128 value_var = prop.unix_name + '_value' | 141 c.Substitute({'value_var': value_var, 'key': prop.name, 'src': src}) |
| 129 c.Append('Value* %(value_var)s = NULL;') | |
| 130 c.Append( | |
| 131 'if (!%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s))') | |
| 132 if prop.optional: | |
| 133 c.Append(' return true;') | |
| 134 else: | |
| 135 c.Append(' return false;') | |
| 136 c.Append() | |
| 137 c.Concat(self._GeneratePopulateChoices(prop, value_var, dst, 'false')) | |
| 138 c.Substitute({'value_var': value_var, 'key': prop.name, 'src': src}) | |
| 139 else: | |
| 140 if prop.optional: | |
| 141 if prop.type_.is_fundamental: | |
| 142 (c.Sblock('{') | |
| 143 .Append('%(type)s %(name)s_temp;') | |
| 144 .Append('if (%s)' % self._GeneratePopulatePropertyFunctionCall( | |
| 145 prop, src, '&%s_temp' % prop.unix_name)) | |
| 146 .Append(' out->%(name)s.reset(new %(type)s(%(name)s_temp));') | |
| 147 .Eblock('}') | |
| 148 ) | |
| 149 else: | |
| 150 raise NotImplementedError('Optional %s not implemented' % prop.type_) | |
| 151 else: | |
| 152 (c.Append('if (!%s)' % | |
| 153 self._GeneratePopulatePropertyFunctionCall( | |
| 154 prop, src, '&' + dst_member)) | |
| 155 .Append(' return false;') | |
| 156 ) | |
| 157 c.Substitute({ | |
| 158 'name': prop.unix_name, | |
| 159 'type': self._cpp_type_generator.GetType(prop) | |
| 160 }) | |
| 161 return c | 142 return c |
| 162 | 143 |
| 163 def _GeneratePopulatePropertyFunctionCall(self, prop, src, dst): | |
| 164 """Generates the function call that populates the given property. | |
| 165 | |
| 166 src: DictionaryValue* | |
| 167 dst: Property* or scoped_ptr<Property> | |
| 168 """ | |
| 169 if prop.type_.is_fundamental: | |
| 170 populate_line = cpp_util.GetFundamentalValue( | |
| 171 prop, src, prop.name, dst) | |
| 172 elif prop.type_ in (PropertyType.REF, PropertyType.OBJECT): | |
| 173 populate_line = '%(type)s::Populate(*%(src)s, %(dst)s)' | |
| 174 else: | |
| 175 raise NotImplementedError('%s populate is not implemented' % | |
| 176 prop.type_) | |
| 177 return populate_line | |
| 178 | |
| 179 def _GenerateTypeToValue(self, cpp_namespace, type_): | 144 def _GenerateTypeToValue(self, cpp_namespace, type_): |
| 180 """Generates a function that serializes the type into a |DictionaryValue|. | 145 """Generates a function that serializes the type into a |DictionaryValue|. |
| 181 """ | 146 """ |
| 182 c = code.Code() | 147 c = code.Code() |
| 183 (c.Sblock('scoped_ptr<DictionaryValue> %s::ToValue() const {' % | 148 (c.Sblock('scoped_ptr<DictionaryValue> %s::ToValue() const {' % |
| 184 cpp_namespace) | 149 cpp_namespace) |
| 185 .Append('scoped_ptr<DictionaryValue> value(new DictionaryValue());') | 150 .Append('scoped_ptr<DictionaryValue> value(new DictionaryValue());') |
| 186 .Append() | 151 .Append() |
| 187 ) | 152 ) |
| 188 for prop in type_.properties.values(): | 153 for prop in type_.properties.values(): |
| 189 c.Concat(self._CreateValueFromProperty(prop, prop.unix_name, 'value')) | 154 c.Concat(self._CreateValueFromProperty(prop, prop.unix_name, 'value')) |
| 190 (c.Append() | 155 (c.Append() |
| 191 .Append('return value.Pass();') | 156 .Append('return value.Pass();') |
| 192 .Eblock('}') | 157 .Eblock('}') |
| 193 ) | 158 ) |
| 194 return c | 159 return c |
| 195 | 160 |
| 196 def _CreateValueFromProperty(self, prop, var, dst): | 161 def _CreateValueFromProperty(self, prop, var, dst): |
| 197 """Generates code to serialize a single property in a type. | 162 """Generates code to serialize a single property in a type. |
| 198 | 163 |
| 199 prop: Property to create from | 164 prop: Property to create from |
| 200 var: variable with value to create from | 165 var: variable with value to create from |
| 201 """ | 166 """ |
| 202 c = code.Code() | 167 c = code.Code() |
| 203 if prop.optional: | 168 if prop.optional: |
| 204 c.Sblock('if (%s.get())' % var) | 169 c.Sblock('if (%s.get())' % var) |
| 205 if prop.type_ == PropertyType.ARRAY: | 170 if prop.type_ == PropertyType.ARRAY: |
| 206 c.Append('%s;' % self._util_cc_helper.SetArray(prop, var, prop.name, dst)) | 171 c.Append('%s;' % self._util_cc_helper.PopulateDictionaryFromArray( |
| 172 prop, var, prop.name, dst)) |
| 207 else: | 173 else: |
| 208 c.Append('%s->SetWithoutPathExpansion("%s", %s);' % | 174 c.Append('%s->SetWithoutPathExpansion("%s", %s);' % |
| 209 (dst, prop.name, cpp_util.CreateValueFromSingleProperty(prop, var))) | 175 (dst, prop.name, cpp_util.CreateValueFromSingleProperty(prop, var))) |
| 210 return c | 176 return c |
| 211 | 177 |
| 212 def _GenerateFunction(self, function): | 178 def _GenerateFunction(self, function): |
| 213 """Generates the definitions for function structs. | 179 """Generates the definitions for function structs. |
| 214 """ | 180 """ |
| 215 classname = cpp_util.Classname(function.name) | 181 classname = cpp_util.Classname(function.name) |
| 216 c = code.Code() | 182 c = code.Code() |
| (...skipping 26 matching lines...) Expand all Loading... |
| 243 Params. | 209 Params. |
| 244 """ | 210 """ |
| 245 c = code.Code() | 211 c = code.Code() |
| 246 num_required = 0 | 212 num_required = 0 |
| 247 for param in function.params: | 213 for param in function.params: |
| 248 if not param.optional: | 214 if not param.optional: |
| 249 num_required += 1 | 215 num_required += 1 |
| 250 if num_required == len(function.params): | 216 if num_required == len(function.params): |
| 251 c.Append('if (%(var)s.GetSize() != %(total)d)') | 217 c.Append('if (%(var)s.GetSize() != %(total)d)') |
| 252 elif not num_required: | 218 elif not num_required: |
| 253 c.Append('if (%(var)s.GetSize() > %(total)s)') | 219 c.Append('if (%(var)s.GetSize() > %(total)d)') |
| 254 else: | 220 else: |
| 255 c.Append('if (%(var)s.GetSize() < %(required)d' | 221 c.Append('if (%(var)s.GetSize() < %(required)d' |
| 256 ' || %(var)s.GetSize() > %(total)d)') | 222 ' || %(var)s.GetSize() > %(total)d)') |
| 257 c.Append(' return scoped_ptr<Params>();') | 223 c.Append(' return scoped_ptr<Params>();') |
| 258 c.Substitute({ | 224 c.Substitute({ |
| 259 'var': var, | 225 'var': var, |
| 260 'required': num_required, | 226 'required': num_required, |
| 261 'total': len(function.params), | 227 'total': len(function.params), |
| 262 }) | 228 }) |
| 263 return c | 229 return c |
| 264 | 230 |
| 265 def _GenerateFunctionParamsCreate(self, function): | 231 def _GenerateFunctionParamsCreate(self, function): |
| 266 """Generate function to create an instance of Params given a pointer. | 232 """Generate function to create an instance of Params. The generated |
| 233 function takes a ListValue of arguments. |
| 267 """ | 234 """ |
| 268 classname = cpp_util.Classname(function.name) | 235 classname = cpp_util.Classname(function.name) |
| 269 c = code.Code() | 236 c = code.Code() |
| 270 (c.Append('// static') | 237 (c.Append('// static') |
| 271 .Sblock('scoped_ptr<%(classname)s::Params> %(classname)s::Params::Create' | 238 .Sblock('scoped_ptr<%(classname)s::Params> %(classname)s::Params::Create' |
| 272 '(const ListValue& args) {') | 239 '(const ListValue& args) {') |
| 273 .Concat(self._GenerateParamsCheck(function, 'args')) | 240 .Concat(self._GenerateParamsCheck(function, 'args')) |
| 274 .Append('scoped_ptr<Params> params(new Params());') | 241 .Append('scoped_ptr<Params> params(new Params());') |
| 275 ) | 242 ) |
| 276 c.Substitute({'classname': classname}) | 243 c.Substitute({'classname': classname}) |
| 277 | 244 |
| 278 for i, param in enumerate(function.params): | 245 for i, param in enumerate(function.params): |
| 279 dst = 'params->' + param.unix_name | |
| 280 # Any failure will cause this function to return. If any argument is | 246 # Any failure will cause this function to return. If any argument is |
| 281 # incorrect or missing, those following it are not processed. Note that | 247 # incorrect or missing, those following it are not processed. Note that |
| 282 # this is still correct in the case of multiple optional arguments as an | 248 # this is still correct in the case of multiple optional arguments as an |
| 283 # optional argument at position 4 cannot exist without an argument at | 249 # optional argument at position 4 cannot exist without an argument at |
| 284 # position 3. | 250 # position 3. |
| 251 failure_value = 'scoped_ptr<Params>()' |
| 285 if param.optional: | 252 if param.optional: |
| 286 failure_value = 'params.Pass()' | 253 arg_missing_value = 'params.Pass()' |
| 287 else: | 254 else: |
| 288 failure_value = 'scoped_ptr<Params>()' | 255 arg_missing_value = failure_value |
| 289 c.Append() | 256 c.Append() |
| 290 param_var = param.unix_name + '_param' | 257 value_var = param.unix_name + '_value' |
| 291 # TODO(calamity): Return error on incorrect argument type | 258 (c.Append('Value* %(value_var)s = NULL;') |
| 292 if param.type_ == PropertyType.ARRAY: | 259 .Append('if (!args.Get(%(i)s, &%(value_var)s) || ' |
| 293 # util_cc_helper deals with optional and required arrays | 260 '%(value_var)s->IsType(Value::TYPE_NULL))') |
| 294 (c.Append('ListValue* %(param_var)s = NULL;') | 261 .Append(' return %s;' % arg_missing_value) |
| 295 .Append('if (!args.GetList(%(i)d, &%(param_var)s))') | 262 .Concat(self._GeneratePopulatePropertyFromValue( |
| 296 .Append(' return %s;' % failure_value) | 263 param, value_var, 'params', failure_value)) |
| 297 .Append('if (!%s)' % self._util_cc_helper.GetArrayFromList( | 264 ) |
| 298 param, param_var, dst)) | 265 c.Substitute({'value_var': value_var, 'i': i}) |
| 299 .Append(' return %s;' % failure_value) | |
| 300 ) | |
| 301 c.Substitute({'param_var': param_var, 'i': i}) | |
| 302 elif param.type_ == PropertyType.CHOICES: | |
| 303 value_var = param.unix_name + '_value' | |
| 304 (c.Append('Value* %(value_var)s = NULL;') | |
| 305 .Append('if (!args.Get(%(i)s, &%(value_var)s))') | |
| 306 .Append(' return %s;' % failure_value) | |
| 307 .Append() | |
| 308 .Concat(self._GeneratePopulateChoices(param, value_var, 'params', | |
| 309 'scoped_ptr<Params>()')) | |
| 310 ) | |
| 311 c.Substitute({'value_var': value_var, 'i': i}) | |
| 312 else: | |
| 313 if param.optional: | |
| 314 dst = dst + '.get()' | |
| 315 else: | |
| 316 dst = '&' + dst | |
| 317 if param.type_ in (PropertyType.REF, PropertyType.OBJECT): | |
| 318 (c.Append('DictionaryValue* %s = NULL;' % param_var) | |
| 319 .Append('if (!args.GetDictionary(%d, &%s))' % (i, param_var)) | |
| 320 .Append(' return %s;' % failure_value) | |
| 321 ) | |
| 322 if param.optional: | |
| 323 c.Append('params->%s.reset(new %s());' % | |
| 324 (param.unix_name, cpp_util.Classname(param.name))) | |
| 325 (c.Append('if (!%(ctype)s::Populate(*%(var)s, %(dst)s))' % { | |
| 326 'var': param_var, 'dst': dst, | |
| 327 'ctype': self._cpp_type_generator.GetType(param) | |
| 328 }) | |
| 329 .Append(' return %s;' % failure_value) | |
| 330 ) | |
| 331 elif param.type_.is_fundamental: | |
| 332 if param.optional: | |
| 333 (c.Sblock('{') | |
| 334 .Append('%(type)s %(name)s_temp;') | |
| 335 .Append('if (%s)' % cpp_util.GetValueFromList( | |
| 336 param, 'args', i, '&%s_temp' % param.unix_name)) | |
| 337 .Append( | |
| 338 ' params->%(name)s.reset(new %(type)s(%(name)s_temp));') | |
| 339 .Eblock('}') | |
| 340 ) | |
| 341 c.Substitute({ | |
| 342 'name': param.unix_name, | |
| 343 'type': self._cpp_type_generator.GetType(param), | |
| 344 }) | |
| 345 else: | |
| 346 (c.Append( | |
| 347 'if (!%s)' % cpp_util.GetValueFromList(param, 'args', i, dst)) | |
| 348 .Append(' return %s;' % failure_value) | |
| 349 ) | |
| 350 else: | |
| 351 raise NotImplementedError('%s parameter is not supported' % | |
| 352 param.type_) | |
| 353 (c.Append() | 266 (c.Append() |
| 354 .Append('return params.Pass();') | 267 .Append('return params.Pass();') |
| 355 .Eblock('}') | 268 .Eblock('}') |
| 269 .Append() |
| 356 ) | 270 ) |
| 357 | 271 |
| 358 return c | 272 return c |
| 359 | 273 |
| 274 def _GeneratePopulatePropertyFromValue( |
| 275 self, prop, value_var, dst, failure_value, check_type=True): |
| 276 """Generates code to populate a model.Property given a Value*. The |
| 277 existence of data inside the Value* is assumed so checks for existence |
| 278 should be performed before the code this generates. |
| 279 |
| 280 prop: the property the code is populating. |
| 281 value_var: a Value* that should represent |prop|. |
| 282 dst: the object with |prop| as a member. |
| 283 failure_value: the value to return if |prop| cannot be extracted from |
| 284 |value_var| |
| 285 check_type: if true, will check if |value_var| is the correct Value::Type |
| 286 """ |
| 287 c = code.Code() |
| 288 c.Sblock('{') |
| 289 |
| 290 if check_type: |
| 291 (c.Append('if (!%(value_var)s->IsType(%(value_type)s))') |
| 292 .Append(' return %(failure_value)s;') |
| 293 ) |
| 294 |
| 295 if prop.type_.is_fundamental: |
| 296 if prop.optional: |
| 297 (c.Append('%(ctype)s temp;') |
| 298 .Append('if (%s)' % |
| 299 cpp_util.GetAsFundamentalValue(prop, value_var, '&temp')) |
| 300 .Append(' %(dst)s->%(name)s.reset(new %(ctype)s(temp));') |
| 301 ) |
| 302 else: |
| 303 (c.Append('if (!%s)' % |
| 304 cpp_util.GetAsFundamentalValue( |
| 305 prop, value_var, '&%s->%s' % (dst, prop.unix_name))) |
| 306 .Append('return %(failure_value)s;') |
| 307 ) |
| 308 elif prop.type_ in (PropertyType.OBJECT, PropertyType.REF): |
| 309 if prop.optional: |
| 310 (c.Append('DictionaryValue* dictionary = NULL;') |
| 311 .Append('if (!%(value_var)s->GetAsDictionary(&dictionary))') |
| 312 .Append(' return %(failure_value)s;') |
| 313 .Append('scoped_ptr<%(ctype)s> temp(new %(ctype)s());') |
| 314 .Append('if (!%(ctype)s::Populate(*dictionary, temp.get()))') |
| 315 .Append(' return %(failure_value)s;') |
| 316 .Append('%(dst)s->%(name)s = temp.Pass();') |
| 317 ) |
| 318 else: |
| 319 (c.Append('DictionaryValue* dictionary = NULL;') |
| 320 .Append('if (!%(value_var)s->GetAsDictionary(&dictionary))') |
| 321 .Append(' return %(failure_value)s;') |
| 322 .Append( |
| 323 'if (!%(ctype)s::Populate(*dictionary, &%(dst)s->%(name)s))') |
| 324 .Append(' return %(failure_value)s;') |
| 325 ) |
| 326 elif prop.type_ == PropertyType.ARRAY: |
| 327 # util_cc_helper deals with optional and required arrays |
| 328 (c.Append('ListValue* list = NULL;') |
| 329 .Append('if (!%(value_var)s->GetAsList(&list))') |
| 330 .Append(' return %s;' % failure_value) |
| 331 .Append('if (!%s)' % self._util_cc_helper.PopulateArrayFromList( |
| 332 prop, 'list', dst + '->' + prop.unix_name)) |
| 333 .Append(' return %s;' % failure_value) |
| 334 ) |
| 335 elif prop.type_ == PropertyType.CHOICES: |
| 336 return self._GeneratePopulateChoices(prop, value_var, dst, failure_value) |
| 337 else: |
| 338 raise NotImplementedError(prop.type_) |
| 339 c.Eblock('}') |
| 340 c.Substitute({ |
| 341 'value_var': value_var, |
| 342 'name': prop.unix_name, |
| 343 'dst': dst, |
| 344 'ctype': self._cpp_type_generator.GetType(prop), |
| 345 'failure_value': failure_value, |
| 346 'value_type': cpp_util.GetValueType(prop), |
| 347 }) |
| 348 return c |
| 349 |
| 360 def _GeneratePopulateChoices(self, prop, value_var, dst, failure_value): | 350 def _GeneratePopulateChoices(self, prop, value_var, dst, failure_value): |
| 361 """Generates the code to populate a PropertyType.CHOICES parameter or | 351 """Generates the code to populate a PropertyType.CHOICES parameter or |
| 362 property. | 352 property. The existence of data inside the Value* is assumed so checks for |
| 353 existence should be performed before the code this generates. |
| 363 | 354 |
| 364 value_var: Value* | 355 prop: the property the code is populating.. |
| 365 dst: Type* or scoped_ptr<Params> | 356 value_var: a Value* that should represent |prop|. |
| 366 failure_value: the value to return on failure. Check if the property is | 357 dst: the object with |prop| as a member. |
| 367 optional BEFORE the code generated by this method as failure_value will be | 358 failure_value: the value to return if |prop| cannot be extracted from |
| 368 used to indicate a parsing error. | 359 |value_var| |
| 369 """ | 360 """ |
| 370 type_var = '%s->%s_type' % (dst, prop.unix_name) | 361 type_var = '%s->%s_type' % (dst, prop.unix_name) |
| 371 | 362 |
| 372 c = code.Code() | 363 c = code.Code() |
| 373 c.Append('%s = %s;' % | 364 c.Append('%s = %s;' % |
| 374 (type_var, self._cpp_type_generator.GetChoiceEnumNoneValue(prop))) | 365 (type_var, self._cpp_type_generator.GetChoiceEnumNoneValue(prop))) |
| 375 c.Sblock('switch (%s->GetType()) {' % value_var) | 366 c.Sblock('switch (%s->GetType()) {' % value_var) |
| 376 for choice in self._cpp_type_generator.GetExpandedChoicesInParams([prop]): | 367 for choice in self._cpp_type_generator.GetExpandedChoicesInParams([prop]): |
| 377 current_choice = '%s->%s' % (dst, choice.unix_name) | 368 (c.Sblock('case %s: {' % cpp_util.GetValueType(choice)) |
| 378 if choice.type_.is_fundamental: | 369 .Concat(self._GeneratePopulatePropertyFromValue( |
| 379 c.Sblock('case %s: {' % { | 370 choice, value_var, dst, failure_value, check_type=False)) |
| 380 PropertyType.STRING: 'Value::TYPE_STRING', | 371 .Append('%s = %s;' % |
| 381 PropertyType.INTEGER: 'Value::TYPE_INTEGER', | 372 (type_var, |
| 382 PropertyType.BOOLEAN: 'Value::TYPE_BOOLEAN', | 373 self._cpp_type_generator.GetChoiceEnumValue( |
| 383 PropertyType.DOUBLE: 'Value::TYPE_DOUBLE' | 374 prop, choice.type_))) |
| 384 }[choice.type_]) | |
| 385 | |
| 386 (c.Append('%(type_var)s = %(enum_value)s;') | |
| 387 .Append('%s.reset(new %s());' % | |
| 388 (current_choice, self._cpp_type_generator.GetType(choice))) | |
| 389 .Append('if (!%s)' % | |
| 390 cpp_util.GetAsFundamentalValue( | |
| 391 choice, value_var, current_choice + '.get()')) | |
| 392 .Append(' return %s;' % failure_value) | |
| 393 .Append('break;') | 375 .Append('break;') |
| 394 .Eblock('}') | 376 .Eblock('}') |
| 395 ) | |
| 396 elif choice.type_ == PropertyType.ARRAY: | |
| 397 # util_cc_helper deals with optional and required arrays | |
| 398 (c.Sblock('case Value::TYPE_LIST: {') | |
| 399 .Append('%(type_var)s = %(enum_value)s;') | |
| 400 .Append('if (!%s)' % self._util_cc_helper.GetArrayFromList( | |
| 401 choice, | |
| 402 'static_cast<ListValue*>(%s)' % value_var, | |
| 403 current_choice)) | |
| 404 .Append(' return %s;' % failure_value) | |
| 405 .Append('break;') | |
| 406 .Eblock('}') | |
| 407 ) | |
| 408 else: | |
| 409 raise NotImplementedError(choice.type_) | |
| 410 c.Substitute({ | |
| 411 'type_var': type_var, | |
| 412 'enum_value': self._cpp_type_generator.GetChoiceEnumValue( | |
| 413 prop, choice.type_), | |
| 414 }) | |
| 415 if not prop.optional: | |
| 416 (c.Append('default:') | |
| 417 .Append(' return %s;' % failure_value) | |
| 418 ) | 377 ) |
| 378 (c.Append('default:') |
| 379 .Append(' return %s;' % failure_value) |
| 380 ) |
| 419 c.Eblock('}') | 381 c.Eblock('}') |
| 420 return c | 382 return c |
| 421 | 383 |
| 422 def _GenerateFunctionResultCreate(self, function): | 384 def _GenerateFunctionResultCreate(self, function): |
| 423 """Generate function to create a Result given the return value. | 385 """Generate function to create a Result given the return value. |
| 424 """ | 386 """ |
| 425 classname = cpp_util.Classname(function.name) | 387 classname = cpp_util.Classname(function.name) |
| 426 c = code.Code() | 388 c = code.Code() |
| 427 params = function.callback.params | 389 params = function.callback.params |
| 390 |
| 428 if not params: | 391 if not params: |
| 429 (c.Append('Value* %s::Result::Create() {' % classname) | 392 (c.Append('Value* %s::Result::Create() {' % classname) |
| 430 .Append(' return Value::CreateNullValue();') | 393 .Append(' return Value::CreateNullValue();') |
| 431 .Append('}') | 394 .Append('}') |
| 432 ) | 395 ) |
| 433 else: | 396 else: |
| 434 # If there is a single parameter, this is straightforward. However, if | 397 # If there is a single parameter, this is straightforward. However, if |
| 435 # the callback parameter is of 'choices', this generates a Create method | 398 # the callback parameter is of 'choices', this generates a Create method |
| 436 # for each choice. This works because only 1 choice can be returned at a | 399 # for each choice. This works because only 1 choice can be returned at a |
| 437 # time. | 400 # time. |
| 438 for param in self._cpp_type_generator.GetExpandedChoicesInParams(params): | 401 for param in self._cpp_type_generator.GetExpandedChoicesInParams(params): |
| 439 arg = cpp_util.GetConstParameterDeclaration( | 402 # We treat this argument as 'required' to avoid wrapping it in a |
| 440 param, self._cpp_type_generator) | 403 # scoped_ptr if it's optional. |
| 404 param_copy = param.Copy() |
| 405 param_copy.optional = False |
| 441 c.Sblock('Value* %(classname)s::Result::Create(%(arg)s) {') | 406 c.Sblock('Value* %(classname)s::Result::Create(%(arg)s) {') |
| 442 if param.type_ == PropertyType.ARRAY: | 407 if param_copy.type_ == PropertyType.ARRAY: |
| 443 (c.Append('ListValue* value = new ListValue();') | 408 (c.Append('ListValue* value = new ListValue();') |
| 444 .Append('%s;' % self._util_cc_helper.SetArrayToList( | 409 .Append('%s;' % self._util_cc_helper.PopulateListFromArray( |
| 445 param, param.unix_name, 'value')) | 410 param_copy, param_copy.unix_name, 'value')) |
| 446 .Append('return value;') | 411 .Append('return value;') |
| 447 ) | 412 ) |
| 448 else: | 413 else: |
| 449 c.Append('return %s;' % cpp_util.CreateValueFromSingleProperty(param, | 414 c.Append('return %s;' % |
| 450 param.unix_name)) | 415 cpp_util.CreateValueFromSingleProperty(param_copy, |
| 451 c.Substitute({'classname': classname, 'arg': arg}) | 416 param_copy.unix_name)) |
| 417 c.Substitute({'classname': classname, |
| 418 'arg': cpp_util.GetParameterDeclaration( |
| 419 param_copy, self._cpp_type_generator.GetType(param_copy)) |
| 420 }) |
| 452 c.Eblock('}') | 421 c.Eblock('}') |
| 453 | 422 |
| 454 return c | 423 return c |
| OLD | NEW |