OLD | NEW |
---|---|
(Empty) | |
1 # Copyright (C) 2013 Google Inc. All rights reserved. | |
2 # | |
3 # Redistribution and use in source and binary forms, with or without | |
4 # modification, are permitted provided that the following conditions are | |
5 # met: | |
6 # | |
7 # * Redistributions of source code must retain the above copyright | |
8 # notice, this list of conditions and the following disclaimer. | |
9 # * Redistributions in binary form must reproduce the above | |
10 # copyright notice, this list of conditions and the following disclaimer | |
11 # in the documentation and/or other materials provided with the | |
12 # distribution. | |
13 # * Neither the name of Google Inc. nor the names of its | |
14 # contributors may be used to endorse or promote products derived from | |
15 # this software without specific prior written permission. | |
16 # | |
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
28 | |
29 """Builds an IdlDefinitions object from an AST (produced by blink_idl_parser)."" " | |
30 | |
31 from idl_definitions import IdlDefinitions, IdlInterface, IdlException, IdlOpera tion, IdlCallbackFunction, IdlArgument, IdlAttribute, IdlConstant, IdlEnum, IdlT ypedef, IdlUnionType | |
32 | |
33 SPECIAL_KEYWORD_LIST = ['GETTER', 'SETTER', 'DELETER'] | |
34 | |
35 | |
36 def idl_definitions_from_ast(node): | |
haraken
2013/07/22 01:50:23
Nit: build_idl_definitions_from_ast ?
Nils Barth (inactive)
2013/07/22 06:32:01
Done.
| |
37 if node is None: | |
38 return None | |
39 node_class = node.GetClass() | |
40 if node_class != 'File': | |
41 raise ValueError('Unrecognized node class: %s' % node_class) | |
42 return file_node_to_idl_definitions(node) | |
43 | |
44 | |
45 def file_node_to_idl_definitions(node): | |
46 callback_functions = {} | |
47 enumerations = {} | |
48 exceptions = {} | |
49 file_name = node.GetName() # FIXME: only needed for Perl, remove later | |
50 interfaces = {} | |
51 typedefs = {} | |
52 | |
53 children = node.GetChildren() | |
54 for child in children: | |
55 child_class = child.GetClass() | |
56 if child_class == 'Interface': | |
57 interface = interface_node_to_idl_interface(child) | |
58 interfaces[interface.name] = interface | |
59 elif child_class == 'Exception': | |
60 exception = exception_node_to_idl_exception(child) | |
61 exceptions[exception.name] = exception | |
62 elif child_class == 'Typedef': | |
63 type_name = child.GetName() | |
64 typedefs[type_name] = typedef_node_to_idl_typedef(child) | |
65 elif child_class == 'Enum': | |
66 enumeration = enum_node_to_idl_enum(child) | |
67 enumerations[enumeration.name] = enumeration | |
68 elif child_class == 'Callback': | |
69 callback_function = callback_node_to_idl_callback_function(child) | |
70 callback_functions[callback_function.name] = callback_function | |
71 elif child_class == 'Implements': | |
72 # Implements is handled at the interface merging step | |
73 pass | |
74 else: | |
75 raise ValueError('Unrecognized node class: %s' % child_class) | |
76 | |
77 return IdlDefinitions(callback_functions=callback_functions, enumerations=en umerations, exceptions=exceptions, file_name=file_name, interfaces=interfaces, t ypedefs=typedefs) | |
78 | |
79 # Interface | |
haraken
2013/07/22 01:50:23
# Definitions for Interface components
Nils Barth (inactive)
2013/07/22 06:32:01
Done. Slight wording change to stay closer to spec
| |
80 | |
81 | |
82 def interface_node_to_idl_interface(node): | |
83 attributes = [] | |
84 constants = [] | |
85 constructors = None | |
86 custom_constructors = None | |
87 extended_attributes = None | |
haraken
2013/07/22 01:50:23
Nit: extended_attributes = {}
Nils Barth (inactive)
2013/07/22 06:32:01
That’s handled by IdlDefinitions.__init__ -- I’m u
| |
88 functions = [] | |
haraken
2013/07/22 01:50:23
Probably we should rename 'function' to 'operation
Nils Barth (inactive)
2013/07/22 06:32:01
(>.<) Missed this one. Fixed throughout.
| |
89 is_callback = node.GetProperty('CALLBACK') or False | |
90 # FIXME: uppercase 'Partial' in base IDL parser | |
91 is_partial = node.GetProperty('Partial') or False | |
92 name = node.GetName() | |
93 parent = None | |
94 | |
95 children = node.GetChildren() | |
96 for child in children: | |
97 child_class = child.GetClass() | |
98 if child_class == 'Attribute': | |
99 attribute = attribute_node_to_idl_attribute(child) | |
100 # FIXME: This is a hack to support [CustomConstructor] for | |
101 # window.HTMLImageElement. Remove the hack. | |
102 clear_constructor_attributes(attribute.extended_attributes) | |
103 attributes.append(attribute) | |
104 elif child_class == 'Const': | |
105 constants.append(constant_node_to_idl_constant(child)) | |
106 elif child_class == 'ExtAttributes': | |
107 extended_attributes = ext_attributes_node_to_extended_attributes(chi ld) | |
108 constructors, custom_constructors = extended_attributes_to_construct ors(extended_attributes) | |
109 clear_constructor_attributes(extended_attributes) | |
110 elif child_class == 'Operation': | |
111 functions.append(operation_node_to_idl_operation(child)) | |
112 elif child_class == 'Inherit': | |
113 parent = child.GetName() | |
114 else: | |
115 raise ValueError('Unrecognized node class: %s' % child_class) | |
116 | |
117 return IdlInterface(name=name, attributes=attributes, constants=constants, c onstructors=constructors, custom_constructors=custom_constructors, extended_attr ibutes=extended_attributes, functions=functions, is_callback=is_callback, is_par tial=is_partial, parent=parent) | |
118 | |
119 | |
120 def attribute_node_to_idl_attribute(node): | |
121 data_type = None | |
122 extended_attributes = {} | |
123 is_nullable = False | |
124 is_read_only = node.GetProperty('READONLY') or False | |
125 is_static = node.GetProperty('STATIC') or False | |
126 name = node.GetName() | |
127 | |
128 children = node.GetChildren() | |
129 for child in children: | |
130 child_class = child.GetClass() | |
131 if child_class == 'Type': | |
132 data_type = type_node_to_type(child) | |
133 is_nullable = child.GetProperty('NULLABLE') or False | |
134 elif child_class == 'ExtAttributes': | |
135 extended_attributes = ext_attributes_node_to_extended_attributes(chi ld) | |
136 else: | |
137 raise ValueError('Unrecognized node class: %s' % child_class) | |
138 | |
139 return IdlAttribute(data_type=data_type, extended_attributes=extended_attrib utes, is_nullable=is_nullable, is_read_only=is_read_only, is_static=is_static, n ame=name) | |
140 | |
141 | |
142 def constant_node_to_idl_constant(node): | |
143 name = node.GetName() | |
144 | |
145 children = node.GetChildren() | |
146 num_children = len(children) | |
147 if num_children < 2 or num_children > 3: | |
148 raise ValueError('Expected 2 or 3 children, got %s' % num_children) | |
149 | |
150 type_node = children[0] | |
151 data_type = type_node_inner_to_type(type_node) | |
haraken
2013/07/22 01:50:23
Shouldn't this be type_node_to_type ?
Nils Barth (inactive)
2013/07/22 06:32:01
No, “inner” is intentional: ConstType is simpler t
| |
152 | |
153 value_node = children[1] | |
154 value_node_class = value_node.GetClass() | |
155 if value_node_class != 'Value': | |
156 raise ValueError('Expected Value node, got %s' % value_node_class) | |
157 value = value_node.GetName() | |
158 | |
159 extended_attributes = None | |
haraken
2013/07/22 01:50:23
Nit: extended_attributes = {}
Nils Barth (inactive)
2013/07/22 06:32:01
(See above.)
| |
160 if num_children == 3: | |
161 ext_attributes_node = children[2] | |
162 extended_attributes = ext_attributes_node_to_extended_attributes(ext_att ributes_node) | |
163 | |
164 return IdlConstant(data_type=data_type, extended_attributes=extended_attribu tes, name=name, value=value) | |
165 | |
166 | |
167 def operation_node_to_idl_operation(node): | |
168 name = node.GetName() | |
169 # FIXME: AST should use None internally | |
170 if name == '_unnamed_': | |
171 name = None | |
172 | |
173 is_static = node.GetProperty('STATIC') or False | |
174 # FIXME: AST should have a specials_node so don't need to hard-code list | |
haraken
2013/07/22 01:50:23
Sorry about my previous comment. Given that 'const
Nils Barth (inactive)
2013/07/22 06:32:01
n/p; got it, done.
| |
175 specials = [] | |
176 property_dictionary = node.GetProperties() | |
177 for special_keyword in SPECIAL_KEYWORD_LIST: | |
178 if special_keyword in property_dictionary: | |
179 specials.append(special_keyword.lower()) | |
180 | |
181 extended_attributes = None | |
haraken
2013/07/22 01:50:23
extentded_attributes = {}
Nils Barth (inactive)
2013/07/22 06:32:01
(See above.)
| |
182 arguments = [] | |
183 return_type = None | |
184 children = node.GetChildren() | |
185 for child in children: | |
186 child_class = child.GetClass() | |
187 if child_class == 'Arguments': | |
188 arguments = arguments_node_to_arguments(child) | |
189 elif child_class == 'Type': | |
190 return_type = type_node_to_type(child) | |
191 elif child_class == 'ExtAttributes': | |
192 extended_attributes = ext_attributes_node_to_extended_attributes(chi ld) | |
193 else: | |
194 raise ValueError('Unrecognized node class: %s' % child_class) | |
195 | |
196 return IdlOperation(name=name, data_type=return_type, extended_attributes=ex tended_attributes, is_static=is_static, arguments=arguments, specials=specials) | |
197 | |
198 | |
199 def arguments_node_to_arguments(node): | |
haraken
2013/07/22 01:50:23
arguments_node_to_idl_arguments ?
Nils Barth (inactive)
2013/07/22 06:32:01
That’s potentially confusing, since it suggests th
| |
200 # [Constructor] and [CustomConstructor] without arguments have None | |
201 # instead of an arguments node (because not [Constructor()]), so | |
202 # special-case this. | |
haraken
2013/07/22 01:50:23
Just to confirm: [Constructor] and [Constructor()]
Nils Barth (inactive)
2013/07/22 06:32:01
Yup, per spec:
http://www.w3.org/TR/WebIDL/#Constr
| |
203 if node is None: | |
204 return None | |
205 arguments = [] | |
206 argument_node_list = node.GetChildren() | |
207 for argument_node in argument_node_list: | |
208 arguments.append(argument_node_to_idl_argument(argument_node)) | |
209 return arguments | |
210 | |
211 | |
212 def argument_node_to_idl_argument(node): | |
213 name = node.GetName() | |
214 | |
215 data_type = None | |
216 extended_attributes = {} | |
217 # FIXME: Boolean values are inconsistent due to Perl compatibility. | |
218 # Make all default to False once Perl removed. | |
219 is_nullable = False | |
220 is_optional = node.GetProperty('OPTIONAL') | |
haraken
2013/07/22 01:50:23
Nit: is_optional = node.GetProperty('OPTIONAL') or
Nils Barth (inactive)
2013/07/22 06:32:01
Nonono, these are all hacks for Perl compatibility
| |
221 is_variadic = None | |
haraken
2013/07/22 01:50:23
Nit: is_variadic = False
Nils Barth (inactive)
2013/07/22 06:32:01
Ditto (Perl hack).
| |
222 children = node.GetChildren() | |
223 for child in children: | |
224 child_class = child.GetClass() | |
225 if child_class == 'Type': | |
226 data_type = type_node_to_type(child) | |
227 is_nullable = child.GetProperty('NULLABLE') | |
haraken
2013/07/22 01:50:23
Nit: is_nullable = child.GetProperty('NULLABLE') o
Nils Barth (inactive)
2013/07/22 06:32:01
Ditto (Perl hack).
| |
228 elif child_class == 'ExtAttributes': | |
229 extended_attributes = ext_attributes_node_to_extended_attributes(chi ld) | |
haraken
2013/07/22 01:50:23
'ext_attributes' and 'extended_attributes' are mix
Nils Barth (inactive)
2013/07/22 06:32:01
This is following the spec: the grammar rule is ca
| |
230 elif child_class == 'Argument': | |
231 child_name = child.GetName() | |
232 if child_name != '...': | |
233 raise ValueError('Unrecognized Argument node; expected "...", go t "%s"' % child_name) | |
234 is_variadic = child.GetProperty('ELLIPSIS') or False | |
235 else: | |
236 raise ValueError('Unrecognized node class: %s' % child_class) | |
237 | |
238 return IdlArgument(name=name, data_type=data_type, extended_attributes=exten ded_attributes, is_nullable=is_nullable, is_optional=is_optional, is_variadic=is _variadic) | |
239 | |
240 # Minor definitions | |
haraken
2013/07/22 01:50:23
# Definitions of non-Interface components
Nils Barth (inactive)
2013/07/22 06:32:01
Done.
| |
241 | |
242 | |
243 def callback_node_to_idl_callback_function(node): | |
244 name = node.GetName() | |
245 children = node.GetChildren() | |
246 num_children = len(children) | |
247 if num_children != 2: | |
248 raise ValueError('Expected 2 children, got %s' % num_children) | |
249 | |
250 type_node = children[0] | |
251 data_type = type_node_to_type(type_node) | |
252 | |
253 arguments_node = children[1] | |
254 arguments_node_class = arguments_node.GetClass() | |
255 if arguments_node_class != 'Arguments': | |
256 raise ValueError('Expected Value node, got %s' % arguments_node_class) | |
257 arguments = arguments_node_to_arguments(arguments_node) | |
258 | |
259 return IdlCallbackFunction(name=name, data_type=data_type, arguments=argumen ts) | |
260 | |
261 | |
262 def enum_node_to_idl_enum(node): | |
263 name = node.GetName() | |
264 values = [] | |
265 for child in node.GetChildren(): | |
266 values.append(child.GetName()) | |
267 return IdlEnum(name=name, values=values) | |
268 | |
269 | |
270 def exception_operation_node_to_idl_operation(node): | |
haraken
2013/07/22 01:50:23
Shall we add a FIXME that says this is just for co
Nils Barth (inactive)
2013/07/22 06:32:01
I’ve added a note and a FIXME.
I don’t know if we
| |
271 extended_attributes = {} | |
272 name = node.GetName() | |
273 children = node.GetChildren() | |
274 if len(children) < 1 or len(children) > 2: | |
275 raise ValueError('ExceptionOperation node with %s children, expected 1 o r 2' % len(children)) | |
276 | |
277 type_node = children[0] | |
278 return_type = type_node_to_type(type_node) | |
279 | |
280 if len(children) > 1: | |
281 ext_attributes_node = children[1] | |
282 extended_attributes = ext_attributes_node_to_extended_attributes(ext_att ributes_node) | |
283 | |
284 return IdlOperation(name=name, data_type=return_type, extended_attributes=ex tended_attributes) | |
285 | |
286 | |
287 def exception_node_to_idl_exception(node): | |
288 # Exceptions are similar to Interfaces, but simpler | |
289 attributes = [] | |
290 constants = [] | |
291 extended_attributes = None | |
haraken
2013/07/22 01:50:23
Nit: extended_attributes = {}
Nils Barth (inactive)
2013/07/22 06:32:01
(See above.)
| |
292 functions = [] | |
293 name = node.GetName() | |
294 | |
295 children = node.GetChildren() | |
296 for child in children: | |
297 child_class = child.GetClass() | |
298 if child_class == 'Attribute': | |
299 attribute = attribute_node_to_idl_attribute(child) | |
300 attributes.append(attribute) | |
301 elif child_class == 'Const': | |
302 constants.append(constant_node_to_idl_constant(child)) | |
303 elif child_class == 'ExtAttributes': | |
304 extended_attributes = ext_attributes_node_to_extended_attributes(chi ld) | |
305 elif child_class == 'ExceptionOperation': | |
306 functions.append(exception_operation_node_to_idl_operation(child)) | |
307 else: | |
308 raise ValueError('Unrecognized node class: %s' % child_class) | |
309 | |
310 return IdlException(name=name, attributes=attributes, constants=constants, e xtended_attributes=extended_attributes, functions=functions) | |
311 | |
312 | |
313 def typedef_node_to_idl_typedef(node): | |
314 data_type = None | |
315 extended_attributes = None | |
haraken
2013/07/22 01:50:23
Nit: extended_attributes = {}
Nils Barth (inactive)
2013/07/22 06:32:01
(See above.)
| |
316 | |
317 children = node.GetChildren() | |
318 for child in children: | |
319 child_class = child.GetClass() | |
320 if child_class == 'Type': | |
321 data_type = type_node_to_type(child) | |
322 elif child_class == 'ExtAttributes': | |
323 extended_attributes = ext_attributes_node_to_extended_attributes(chi ld) | |
324 raise ValueError('Extended attributes in a typedef are untested!') | |
325 else: | |
326 raise ValueError('Unrecognized node class: %s' % child_class) | |
327 | |
328 return IdlTypedef(data_type=data_type, extended_attributes=extended_attribut es) | |
329 | |
330 # Extended attributes | |
331 | |
332 | |
333 def ext_attributes_node_to_extended_attributes(node): | |
334 """ | |
335 Returns: | |
336 Dictionary of {ExtAttributeName: ExtAttributeValue}. | |
337 Value is usually a string, with three exceptions: | |
338 Constructors: value is a list of Arguments nodes, corresponding to | |
339 possibly signatures of the constructor. | |
340 CustomConstructors: value is a list of Arguments nodes, corresponding to | |
341 possibly signatures of the custom constructor. | |
342 NamedConstructor: value is a Call node, corresponding to the single | |
343 signature of the named constructor. | |
344 """ | |
345 # Primarily just make a dictionary from the children. | |
346 # The only complexity is handling various types of constructors: | |
347 # Constructors and Custom Constructors can have duplicate entries due to | |
348 # overloading, and thus are stored in temporary lists. | |
349 # However, Named Constructors cannot be overloaded, and thus do not have | |
350 # a list. | |
351 # FIXME: Add overloading for Named Constructors and remove custom bindings | |
352 # for HTMLImageElement | |
353 constructors = [] | |
354 custom_constructors = [] | |
355 extended_attributes = {} | |
356 | |
357 attribute_list = node.GetChildren() | |
358 for attribute in attribute_list: | |
359 name = attribute.GetName() | |
360 children = attribute.GetChildren() | |
361 if name in ['Constructor', 'CustomConstructor', 'NamedConstructor']: | |
362 child = None | |
363 child_class = None | |
364 if children: | |
365 if len(children) > 1: | |
366 raise ValueError('ExtAttributes node with %s children, expec ted at most 1' % len(children)) | |
367 child = children[0] | |
368 child_class = child.GetClass() | |
369 if name == 'Constructor': | |
370 if child_class and child_class != 'Arguments': | |
371 raise ValueError('Constructor only supports Arguments as chi ld, but has child of class: %s' % child_class) | |
372 constructors.append(child) | |
373 elif name == 'CustomConstructor': | |
374 if child_class and child_class != 'Arguments': | |
375 raise ValueError('Custom Constructor only supports Arguments as child, but has child of class: %s' % child_class) | |
376 custom_constructors.append(child) | |
377 else: # name == 'NamedConstructor' | |
378 if child_class and child_class != 'Call': | |
379 raise ValueError('Named Constructor only supports Call as ch ild, but has child of class: %s' % child_class) | |
380 extended_attributes[name] = child | |
381 elif children: | |
382 raise ValueError('Non-constructor ExtAttributes node with children: %s' % name) | |
383 else: | |
384 value = attribute.GetProperty('VALUE') | |
385 extended_attributes[name] = value | |
386 | |
387 # Store constructors and custom constructors in special list attributes, | |
388 # which are deleted later. Note plural in key. | |
389 if constructors: | |
390 extended_attributes['Constructors'] = constructors | |
391 if custom_constructors: | |
392 extended_attributes['CustomConstructors'] = custom_constructors | |
393 | |
394 return extended_attributes | |
395 | |
396 | |
397 def extended_attributes_to_constructors(extended_attributes): | |
398 """Returns constructors and custom_constructors (lists of IdlOperations). | |
399 | |
400 Auxiliary function for interface_node_to_idl_interface. | |
401 """ | |
402 constructors = [] | |
403 custom_constructors = [] | |
404 if 'Constructors' in extended_attributes: | |
405 constructor_list = extended_attributes['Constructors'] | |
406 # If not overloaded, have index 0, otherwise index from 1 | |
407 overloaded_index = 0 if len(constructor_list) == 1 else 1 | |
408 for arguments_node in constructor_list: | |
409 name = 'Constructor' | |
410 arguments = arguments_node_to_arguments(arguments_node) | |
411 constructor = IdlOperation(name=name, extended_attributes=extended_a ttributes, overloaded_index=overloaded_index, arguments=arguments) | |
412 constructors.append(constructor) | |
413 overloaded_index += 1 | |
414 | |
415 # Prefix 'CallWith' and 'RaisesException' with 'Constructor' | |
416 # FIXME: Change extended attributes to include prefix explicitly. | |
417 if 'CallWith' in extended_attributes: | |
418 extended_attributes['ConstructorCallWith'] = extended_attributes['Ca llWith'] | |
419 del extended_attributes['CallWith'] | |
420 if 'RaisesException' in extended_attributes: | |
421 extended_attributes['ConstructorRaisesException'] = extended_attribu tes['RaisesException'] | |
422 del extended_attributes['RaisesException'] | |
423 | |
424 if 'CustomConstructors' in extended_attributes: | |
425 custom_constructor_list = extended_attributes['CustomConstructors'] | |
426 # If not overloaded, have index 0, otherwise index from 1 | |
427 overloaded_index = 0 if len(custom_constructor_list) == 1 else 1 | |
428 for arguments_node in custom_constructor_list: | |
429 name = 'CustomConstructor' | |
430 arguments = arguments_node_to_arguments(arguments_node) | |
431 custom_constructor = IdlOperation(name=name, extended_attributes=ext ended_attributes, overloaded_index=overloaded_index, arguments=arguments) | |
432 custom_constructors.append(custom_constructor) | |
433 overloaded_index += 1 | |
434 | |
435 if 'NamedConstructor' in extended_attributes: | |
436 name = 'NamedConstructor' | |
437 call_node = extended_attributes['NamedConstructor'] | |
438 extended_attributes['NamedConstructor'] = call_node.GetName() | |
439 overloaded_index = None # named constructors are not overloaded | |
440 children = call_node.GetChildren() | |
441 if len(children) != 1: | |
442 raise ValueError('NamedConstructor node expects 1 child, got %s.' % len(children)) | |
443 arguments_node = children[0] | |
444 arguments = arguments_node_to_arguments(arguments_node) | |
445 named_constructor = IdlOperation(name=name, extended_attributes=extended _attributes, overloaded_index=overloaded_index, arguments=arguments) | |
446 constructors.append(named_constructor) | |
447 | |
448 return constructors, custom_constructors | |
449 | |
450 | |
451 def clear_constructor_attributes(extended_attributes): | |
452 # Deletes Constructor*s* (plural), sets Constructor (singular) | |
453 if 'Constructors' in extended_attributes: | |
454 del extended_attributes['Constructors'] | |
455 extended_attributes['Constructor'] = None | |
456 if 'CustomConstructors' in extended_attributes: | |
457 del extended_attributes['CustomConstructors'] | |
458 extended_attributes['CustomConstructor'] = None | |
459 | |
460 | |
461 # Types | |
462 | |
463 | |
464 def type_node_to_type(node): | |
465 children = node.GetChildren() | |
466 if len(children) < 1 or len(children) > 2: | |
467 raise ValueError('Type node expects 1 or 2 children (type + optional arr ay []), got %s (multi-dimensional arrays are not supported).' % len(children)) | |
468 | |
469 type_node_child = children[0] | |
470 data_type = type_node_inner_to_type(type_node_child) | |
471 | |
472 if len(children) == 2: | |
473 array_node = children[1] | |
474 array_node_class = array_node.GetClass() | |
475 if array_node_class != 'Array': | |
476 raise ValueError('Expected Array node as TypeSuffix, got %s node.' % array_node_class) | |
477 data_type += '[]' | |
478 | |
479 return data_type | |
480 | |
481 | |
482 def type_node_inner_to_type(node): | |
483 node_class = node.GetClass() | |
484 if node_class in ['PrimitiveType', 'Typeref']: | |
haraken
2013/07/22 01:50:23
Help me understand: What is Typeref?
Nils Barth (inactive)
2013/07/22 06:32:01
! Good catch! It’s a typo for Type*d*ef in the bas
| |
485 return node.GetName() | |
486 elif node_class == 'Any': | |
487 return 'any' | |
488 elif node_class == 'Sequence': | |
489 return sequence_node_to_type(node) | |
490 elif node_class == 'UnionType': | |
491 return union_type_node_to_idl_union_type(node) | |
492 raise ValueError('Unrecognized node class: %s' % node_class) | |
493 | |
494 | |
495 def sequence_node_to_type(node): | |
496 children = node.GetChildren() | |
497 if len(children) != 1: | |
498 raise ValueError('Sequence node expects exactly 1 child, got %s' % len(c hildren)) | |
499 sequence_child = children[0] | |
500 sequence_child_class = sequence_child.GetClass() | |
501 if sequence_child_class != 'Type': | |
502 raise ValueError('Unrecognized node class: %s' % sequence_child_class) | |
503 sequence_type = type_node_to_type(sequence_child) | |
504 return 'sequence<%s>' % sequence_type | |
505 | |
506 | |
507 def union_type_node_to_idl_union_type(node): | |
508 union_member_types = [] | |
509 for member_type_node in node.GetChildren(): | |
510 member_type = type_node_inner_to_type(member_type_node) | |
haraken
2013/07/22 01:50:23
Shouldn't this be type_node_to_type ?
Nils Barth (inactive)
2013/07/22 06:32:01
Good point. I gave a simple definition for UnionMe
| |
511 union_member_types.append(member_type) | |
512 return IdlUnionType(union_member_types=union_member_types) | |
OLD | NEW |