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

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

Issue 9114036: Code generation for extensions api (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: windows path fix 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
« no previous file with comments | « tools/json_schema_compiler/api_gen_util.gyp ('k') | tools/json_schema_compiler/code.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 # found in the LICENSE file.
4
5 from model import PropertyType
6 import code
7 import cpp_util
8
9 class CCGenerator(object):
10 """A .cc generator for a namespace.
11 """
12 def __init__(self, namespace, cpp_type_generator):
13 self._cpp_type_generator = cpp_type_generator
14 self._namespace = namespace
15 self._target_namespace = (
16 self._cpp_type_generator.GetCppNamespaceName(self._namespace))
17
18 def Generate(self):
19 """Generates a code.Code object with the .cc for a single namespace.
20 """
21 c = code.Code()
22 (c.Append(cpp_util.CHROMIUM_LICENSE)
23 .Append()
24 .Append(cpp_util.GENERATED_FILE_MESSAGE % self._namespace.source_file)
25 .Append()
26 .Append('#include "tools/json_schema_compiler/util.h"')
27 .Append('#include "%s/%s.h"' %
28 (self._namespace.source_file_dir, self._target_namespace))
29 .Append()
30 .Concat(self._cpp_type_generator.GetCppNamespaceStart())
31 .Append()
32 .Append('//')
33 .Append('// Types')
34 .Append('//')
35 .Append()
36 )
37 for type_ in self._namespace.types.values():
38 (c.Concat(self._GenerateType(type_))
39 .Append()
40 )
41 (c.Append('//')
42 .Append('// Functions')
43 .Append('//')
44 .Append()
45 )
46 for function in self._namespace.functions.values():
47 (c.Concat(self._GenerateFunction(function))
48 .Append()
49 )
50 (c.Concat(self._cpp_type_generator.GetCppNamespaceEnd())
51 .Append()
52 )
53 # TODO(calamity): Events
54 return c
55
56 def _GenerateType(self, type_):
57 """Generates the function definitions for a type.
58 """
59 c = code.Code()
60
61 (c.Append('%(classname)s::%(classname)s() {}')
62 .Append('%(classname)s::~%(classname)s() {}')
63 .Append()
64 )
65 c.Substitute({'classname': type_.name})
66
67 c.Concat(self._GenerateTypePopulate(type_))
68 c.Append()
69 # TODO(calamity): deal with non-serializable
70 c.Concat(self._GenerateTypeTovalue(type_))
71 c.Append()
72
73 return c
74
75 def _GenerateTypePopulate(self, type_):
76 """Generates the function for populating a type given a pointer to it.
77 """
78 c = code.Code()
79 (c.Append('// static')
80 .Sblock('bool %(name)s::Populate(const Value& value, %(name)s* out) {')
81 .Append('if (!value.IsType(Value::TYPE_DICTIONARY))')
82 .Append(' return false;')
83 .Append('const DictionaryValue* dict = '
84 'static_cast<const DictionaryValue*>(&value);')
85 .Append()
86 )
87 c.Substitute({'name': type_.name})
88
89 # TODO(calamity): this handle single PropertyType.REF properties.
90 # add ALL the types
91 for prop in type_.properties.values():
92 sub = {'name': prop.name}
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;')
130 .Eblock('}')
131 )
132 return c
133
134 def _GenerateTypeTovalue(self, type_):
135 """Generates a function that serializes the type into a |DictionaryValue|.
136 """
137 c = code.Code()
138 (c.Sblock('DictionaryValue* %s::ToValue() const {' % type_.name)
139 .Append('DictionaryValue* value = new DictionaryValue();')
140 .Append()
141 )
142 name = type_.name.lower()
143 for prop in type_.properties.values():
144 prop_name = name + '_' + prop.name if name else prop.name
145 this_var = prop.name
146 c.Concat(self._CreateValueFromProperty(prop_name, prop, this_var))
147 (c.Append()
148 .Append('return value;')
149 .Eblock('}')
150 )
151 return c
152
153 # TODO(calamity): object and choices prop types
154 def _CreateValueFromProperty(self, name, prop, var):
155 """Generates code to serialize a single property in a type.
156 """
157 c = code.Code()
158 if prop.type_.is_fundamental:
159 c.Append('Value* %s_value = %s;' %
160 (name, cpp_util.CreateFundamentalValue(prop, var)))
161 elif prop.type_ == PropertyType.ARRAY:
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:
185 raise NotImplementedError
186 return c
187
188 def _GenerateFunction(self, function):
189 """Generates the definitions for function structs.
190 """
191 classname = cpp_util.CppName(function.name)
192 c = code.Code()
193
194 # Params::Populate function
195 if function.params:
196 (c.Append('%(name)s::Params::Params() {}')
197 .Append('%(name)s::Params::~Params() {}')
198 .Append()
199 .Concat(self._GenerateFunctionParamsCreate(function))
200 .Append()
201 )
202
203 # Result::Create function
204 c.Concat(self._GenerateFunctionResultCreate(function))
205
206 c.Substitute({'name': classname})
207
208 return c
209
210 def _GenerateFunctionParamsCreate(self, function):
211 """Generate function to create an instance of Params given a pointer.
212 """
213 classname = cpp_util.CppName(function.name)
214 c = code.Code()
215 (c.Append('// static')
216 .Sblock('scoped_ptr<%(classname)s::Params> %(classname)s::Params::Create'
217 '(const ListValue& args) {')
218 .Append('if (args.GetSize() != %d)' % len(function.params))
219 .Append(' return scoped_ptr<Params>();')
220 .Append()
221 .Append('scoped_ptr<Params> params(new Params());')
222 )
223 c.Substitute({'classname': classname})
224
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):
228 sub = {'name': param.name, 'pos': i}
229 c.Append()
230 # TODO(calamity): Make valid for not just objects
231 c.Append('DictionaryValue* %(name)s_param = NULL;')
232 c.Append('if (!args.GetDictionary(%(pos)d, &%(name)s_param))')
233 c.Append(' return scoped_ptr<Params>();')
234 if param.type_ == PropertyType.REF:
235 c.Append('if (!%(ctype)s::Populate(*%(name)s_param, '
236 '&params->%(name)s))')
237 c.Append(' return scoped_ptr<Params>();')
238 sub['ctype'] = self._cpp_type_generator.GetType(param)
239 elif param.type_.is_fundamental:
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:
247 raise NotImplementedError('Choices is unimplemented')
248 else:
249 raise NotImplementedError(param.type_)
250 c.Substitute(sub)
251 c.Append()
252 c.Append('return params.Pass();')
253 c.Eblock('}')
254
255 return c
256
257 def _GenerateFunctionResultCreate(self, function):
258 """Generate function to create a Result given the return value.
259 """
260 classname = cpp_util.CppName(function.name)
261 c = code.Code()
262 c.Append('// static')
263 param = function.callback.param
264 arg = ''
265 if param:
266 if param.type_ == PropertyType.REF:
267 arg = 'const %(type)s& %(name)s'
268 else:
269 arg = 'const %(type)s %(name)s'
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:
280 sub['argname'] = param.name
281 if param.type_.is_fundamental:
282 c.Append('return %s;' %
283 cpp_util.CreateFundamentalValue(param, param.name))
284 elif param.type_ == PropertyType.REF:
285 c.Append('return %(argname)s.ToValue();')
286 elif param.type_ == PropertyType.OBJECT:
287 raise NotImplementedError('Objects not implemented')
288 elif param.type_ == PropertyType.ARRAY:
289 raise NotImplementedError('Arrays not implemented')
290 else:
291 raise NotImplementedError(param.type_)
292 c.Substitute(sub)
293 c.Eblock('}')
294 return c
OLDNEW
« no previous file with comments | « tools/json_schema_compiler/api_gen_util.gyp ('k') | tools/json_schema_compiler/code.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698