Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Side by Side Diff: tools/json_schema_compiler/cc_generator.py

Issue 9309044: Supporting more APIs with json_schema_compiler (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: support for choices Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 '&params->%(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 '&params->%(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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698