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

Side by Side Diff: Source/bindings/scripts/idl_definitions_builder.py

Issue 15801003: IDL parser rewrite in Python (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Ready for review! (cleaner) Created 7 years, 5 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 | Annotate | Revision Log
OLDNEW
(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 """Read an IDL file or complete IDL interface, producing an IdlDefinitions objec t."""
haraken 2013/07/17 02:44:49 Slightly better: "Build an IdlDefinitions object f
Nils Barth (inactive) 2013/07/17 12:05:09 Oops, you’re right (this was the idl_reader commen
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 file_node_to_idl_definitions(node):
haraken 2013/07/17 02:44:49 For readability, I might want to add one more help
Nils Barth (inactive) 2013/07/17 12:05:09 You’re right, that’s clearer. I actually had this
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 callback_functions = []
43 enumerations = []
44 exceptions = {}
45 file_name = node.GetName() # FIXME: only needed for Perl, remove later
46 interfaces = {}
47 typedefs = {}
48
49 children = node.GetChildren()
50 for child in children:
51 child_class = child.GetClass()
52 if child_class == 'Interface':
53 interface = interface_node_to_idl_interface(child)
54 interfaces[interface.name] = interface
55 elif child_class == 'Exception':
56 exception = exception_node_to_idl_exception(child)
57 exceptions[exception.name] = exception
58 elif child_class == 'Typedef':
59 type_name = child.GetName()
60 typedefs[type_name] = typedef_node_to_idl_typedef(child)
61 elif child_class == 'Enum':
62 enumerations.append(enum_node_to_idl_enum(child))
63 elif child_class == 'Callback':
64 callback_functions.append(callback_node_to_idl_callback_function(chi ld))
65 elif child_class == 'Implements':
66 # Implements is handled at the interface merging step
67 pass
haraken 2013/07/17 02:44:49 Help me understand: Why can we skip 'Implements'?
Nils Barth (inactive) 2013/07/17 12:05:09 We should probably handle Implements differently (
68 else:
69 raise ValueError('Unrecognized node class: %s' % child_class)
70
71 return IdlDefinitions(callback_functions=callback_functions, enumerations=en umerations, exceptions=exceptions, file_name=file_name, interfaces=interfaces, typedefs=typedefs)
haraken 2013/07/17 02:44:49 Nit: One unnecessary space before file_name.
Nils Barth (inactive) 2013/07/17 12:05:09 (>.<) Fixed.
72
73 # Interface
74
75
76 def interface_node_to_idl_interface(node):
77 attributes = []
78 constants = []
79 constructors = None
80 custom_constructors = None
81 extended_attributes = None
82 functions = []
83 is_callback = node.GetProperty('CALLBACK') or False
84 # FIXME: uppercase 'Partial' in base IDL parser
85 is_partial = node.GetProperty('Partial') or False
86 name = node.GetName()
87 parent = None
88
89 children = node.GetChildren()
90 for child in children:
91 child_class = child.GetClass()
92 if child_class == 'Attribute':
93 attribute = attribute_node_to_idl_attribute(child)
94 clear_constructor_attributes(attribute.extended_attributes)
haraken 2013/07/17 02:44:49 Would you add the following FIXME? FIXME: This
Nils Barth (inactive) 2013/07/17 12:05:09 Done. Thanks for explaining why we have this!
95 attributes.append(attribute)
96 elif child_class == 'Const':
97 constants.append(constant_node_to_idl_constant(child))
98 elif child_class == 'ExtAttributes':
99 extended_attributes = ext_attributes_node_to_extended_attributes(chi ld)
haraken 2013/07/17 02:44:49 Don't you need to call clear_constructor_attribute
Nils Barth (inactive) 2013/07/17 12:05:09 The clearing is done as part of extended_attribute
100 constructors, custom_constructors = extended_attributes_to_construct ors(extended_attributes)
101 elif child_class == 'Operation':
102 functions.append(operation_node_to_idl_operation(child))
103 elif child_class == 'Inherit':
104 parent = child.GetName()
105 elif child_class == 'ExceptionFieldToString':
haraken 2013/07/17 02:44:49 I don't fully understand why this is needed.
Nils Barth (inactive) 2013/07/17 12:05:09 (See above; this is a single special-case Operatio
106 functions.append(exception_field_to_string_node_to_idl_operation(chi ld))
107 else:
108 raise ValueError('Unrecognized node class: %s' % child_class)
109
110 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)
111
112
113 def attribute_node_to_idl_attribute(node):
114 data_type = None
115 extended_attributes = {}
116 is_nullable = False
117 is_read_only = node.GetProperty('READONLY') or False
118 is_static = node.GetProperty('STATIC') or False
119 name = node.GetName()
120
121 children = node.GetChildren()
122 for child in children:
123 child_class = child.GetClass()
124 if child_class == 'Type':
125 data_type = type_node_to_type(child)
126 is_nullable = child.GetProperty('NULLABLE') or False
127 elif child_class == 'ExtAttributes':
128 extended_attributes = ext_attributes_node_to_extended_attributes(chi ld)
129 else:
130 raise ValueError('Unrecognized node class: %s' % child_class)
131
132 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)
133
134
135 def constant_node_to_idl_constant(node):
136 name = node.GetName()
137
138 children = node.GetChildren()
139 num_children = len(children)
haraken 2013/07/17 02:44:49 Shall we check that num_children > 1 ?
Nils Barth (inactive) 2013/07/17 12:05:09 Good point. It would have thrown an error later, b
140 if num_children > 3:
141 raise ValueError('Expected at most 3 children, got %s' % num_children)
142
143 type_node = children[0]
144 data_type = type_node_inner_to_type(type_node)
145
146 value_node = children[1]
147 value_node_class = value_node.GetClass()
148 if value_node_class != 'Value':
149 raise ValueError('Expected Value node, got %s' % value_node_class)
150 value = value_node.GetName()
151
152 extended_attributes = None
153 if num_children == 3:
154 ext_attributes_node = children[2]
155 extended_attributes = ext_attributes_node_to_extended_attributes(ext_att ributes_node)
156
157 return IdlConstant(data_type=data_type, extended_attributes=extended_attribu tes, name=name, value=value)
158
159
160 def operation_node_to_idl_operation(node):
161 name = node.GetName()
162 # FIXME: AST should use None internally
163 if name == '_unnamed_':
164 name = None
165
166 is_static = node.GetProperty('STATIC') or False
167 specials = []
168 property_dictionary = node.GetProperties()
169 for special_keyword in SPECIAL_KEYWORD_LIST:
haraken 2013/07/17 02:44:49 Why haven't the special keywords parsed in the par
Nils Barth (inactive) 2013/07/17 12:05:09 The special keywords are handled by the lexer and
haraken 2013/07/21 14:31:50 Got it. Given that static, const etc are stored in
170 if special_keyword in property_dictionary:
171 specials.append(special_keyword.lower())
172
173 extended_attributes = None
174 arguments = []
175 return_type = None
176 children = node.GetChildren()
177 for child in children:
178 child_class = child.GetClass()
179 if child_class == 'Arguments':
180 arguments = arguments_node_to_arguments(child)
181 elif child_class == 'Type':
182 return_type = type_node_to_type(child)
183 elif child_class == 'ExtAttributes':
184 extended_attributes = ext_attributes_node_to_extended_attributes(chi ld)
185 else:
186 raise ValueError('Unrecognized node class: %s' % child_class)
187
188 return IdlOperation(name=name, data_type=return_type, extended_attributes=ex tended_attributes, is_static=is_static, arguments=arguments, specials=specials)
189
190
191 def arguments_node_to_arguments(arguments_node):
haraken 2013/07/17 02:44:49 Nit: arguments_node => node (for consistency)
Nils Barth (inactive) 2013/07/17 12:05:09 (>.<) Done.
192 if arguments_node is None:
haraken 2013/07/17 02:44:49 Is this check needed?
Nils Barth (inactive) 2013/07/17 12:05:09 It makes handling constructors much easier, since
haraken 2013/07/21 14:31:50 Makes sense. Given that the spec allows both [Cons
Nils Barth (inactive) 2013/07/22 06:32:01 Got it. Didn’t realize that [Constructor] was one
193 return None
194 arguments = []
195 argument_node_list = arguments_node.GetChildren()
196 for argument_node in argument_node_list:
197 arguments.append(argument_node_to_idl_argument(argument_node))
198 return arguments
199
200
201 def argument_node_to_idl_argument(node):
202 name = node.GetName()
203
204 data_type = None
205 extended_attributes = {}
206 # FIXME: Boolean values are inconsistent due to Perl compatibility.
207 # Make all default to False once Perl removed.
haraken 2013/07/17 02:44:49 You can remove this comment, as the same thing is
Nils Barth (inactive) 2013/07/17 12:05:09 Done. (Actual delete the nested comment, so it’s c
208 is_nullable = False
209 is_optional = node.GetProperty('OPTIONAL')
210 is_variadic = None
211 children = node.GetChildren()
212 for child in children:
213 child_class = child.GetClass()
214 if child_class == 'Type':
215 data_type = type_node_to_type(child)
216 # FIXME: Should end "or False", but use None instead for Perl
217 # compatibility.
218 is_nullable = child.GetProperty('NULLABLE')
219 elif child_class == 'ExtAttributes':
220 extended_attributes = ext_attributes_node_to_extended_attributes(chi ld)
221 elif child_class == 'Argument':
222 child_name = child.GetName()
223 if child_name != '...':
224 raise ValueError('Unrecognized Argument node; expected "...", go t "%s"' % child_name)
225 is_variadic = child.GetProperty('ELLIPSIS') or False
226 else:
227 raise ValueError('Unrecognized node class: %s' % child_class)
228
229 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)
230
231 # Minor definitions
232
233
234 def callback_node_to_idl_callback_function(node):
235 name = node.GetName()
236 children = node.GetChildren()
237 num_children = len(children)
238 if num_children != 2:
239 raise ValueError('Expected 2 children, got %s' % num_children)
240
241 type_node = children[0]
242 data_type = type_node_to_type(type_node)
243
244 arguments_node = children[1]
245 arguments_node_class = arguments_node.GetClass()
246 if arguments_node_class != 'Arguments':
247 raise ValueError('Expected Value node, got %s' % arguments_node_class)
248 arguments = arguments_node_to_arguments(arguments_node)
249
250 return IdlCallbackFunction(name=name, data_type=data_type, arguments=argumen ts)
251
252
253 def enum_node_to_idl_enum(node):
254 name = node.GetName()
255 values = []
256 for child in node.GetChildren():
257 values.append(child.GetName())
258 return IdlEnum(name=name, values=values)
259
260
261 def exception_field_to_string_node_to_idl_operation(node):
262 extended_attributes = {}
263 name = node.GetName()
264 children = node.GetChildren()
haraken 2013/07/17 02:44:49 Shall we check that len(children) > 0 ?
Nils Barth (inactive) 2013/07/17 12:05:09 Done. (As above.)
265 if len(children) > 2:
266 raise ValueError('ExceptionFieldToString node with %s children, expected at most 2' % len(children))
267
268 type_node = children[0]
269 return_type = type_node_to_type(type_node)
270
271 if len(children) > 1:
272 ext_attributes_node = children[1]
273 extended_attributes = ext_attributes_node_to_extended_attributes(ext_att ributes_node)
274
275 return IdlOperation(name=name, data_type=return_type, extended_attributes=ex tended_attributes)
276
277
278 def exception_node_to_idl_exception(node):
279 # Exceptions are similar to Interfaces, but simpler
280 attributes = []
281 constants = []
282 extended_attributes = None
283 functions = []
284 name = node.GetName()
285
286 children = node.GetChildren()
287 for child in children:
288 child_class = child.GetClass()
289 if child_class == 'Attribute':
290 attribute = attribute_node_to_idl_attribute(child)
291 attributes.append(attribute)
292 elif child_class == 'Const':
293 constants.append(constant_node_to_idl_constant(child))
294 elif child_class == 'ExtAttributes':
295 extended_attributes = ext_attributes_node_to_extended_attributes(chi ld)
296 elif child_class == 'Operation':
297 functions.append(operation_node_to_idl_operation(child))
298 elif child_class == 'ExceptionFieldToString':
299 functions.append(exception_field_to_string_node_to_idl_operation(chi ld))
300 else:
301 raise ValueError('Unrecognized node class: %s' % child_class)
302
303 return IdlException(name=name, attributes=attributes, constants=constants, e xtended_attributes=extended_attributes, functions=functions)
304
305
306 def typedef_node_to_idl_typedef(node):
307 data_type = None
308 extended_attributes = None
309
310 children = node.GetChildren()
311 for child in children:
312 child_class = child.GetClass()
313 if child_class == 'Type':
314 data_type = type_node_to_type(child)
315 elif child_class == 'ExtAttributes':
316 extended_attributes = ext_attributes_node_to_extended_attributes(chi ld)
317 raise ValueError('Extended attributes in a typedef are untested!')
318 else:
319 raise ValueError('Unrecognized node class: %s' % child_class)
320
321 return IdlTypedef(data_type=data_type, extended_attributes=extended_attribut es)
322
323 # Extended attributes
324
325
326 def ext_attributes_node_to_extended_attributes(node):
327 """
328 Returns:
329 Dictionary of {ExtAttributeName: ExtAttributeValue}.
330 Value is usually a string, with three exceptions:
331 Constructors: value is a list of Arguments nodes, corresponding to
332 possibly signatures of the constructor.
333 CustomConstructors: value is a list of Arguments nodes, corresponding to
334 possibly signatures of the custom constructor.
335 NamedConstructor: value is a Call node, corresponding to the single
336 signature of the named constructor.
337 """
338 # Primarily just make a dictionary from the children.
339 # The only complexity is handling various types of constructors:
340 # Constructors and Custom Constructors can have duplicate entries due to
341 # overloading, and thus are stored in temporary lists.
342 # However, Named Constructors cannot be overloaded, and thus do not have
haraken 2013/07/17 02:44:49 Actually this should be a FIXME. We want to suppor
Nils Barth (inactive) 2013/07/17 12:05:09 Added FIXME!
343 # a list.
344 constructors = []
345 custom_constructors = []
346 extended_attributes = {}
347
348 attribute_list = node.GetChildren()
349 for attribute in attribute_list:
350 name = attribute.GetName()
351 children = attribute.GetChildren()
352 if name in ['Constructor', 'CustomConstructor', 'NamedConstructor']:
353 child = None
354 child_class = None
355 if children:
356 if len(children) > 1:
357 raise ValueError('ExtAttributes node with %s children, expec ted at most 1' % len(children))
358 child = children[0]
359 child_class = child.GetClass()
360 if name == 'Constructor':
361 if child_class and child_class != 'Arguments':
362 raise ValueError('Constructor only supports Arguments as chi ld, but has child of class: %s' % child_class)
363 constructors.append(child)
364 elif name == 'CustomConstructor':
365 if child_class and child_class != 'Arguments':
366 raise ValueError('Custom Constructor only supports Arguments as child, but has child of class: %s' % child_class)
367 custom_constructors.append(child)
368 else: # name == 'NamedConstructor'
369 if child_class and child_class != 'Call':
370 raise ValueError('Named Constructor only supports Call as ch ild, but has child of class: %s' % child_class)
371 extended_attributes[name] = child
372 elif children:
373 raise ValueError('Non-constructor ExtAttributes node with children: %s' % name)
374 else:
375 value = attribute.GetProperty('VALUE')
376 extended_attributes[name] = value
377
378 # Store constructors and custom constructors in special list attributes,
379 # which are deleted later. Note plural in key.
380 if constructors:
381 extended_attributes['Constructors'] = constructors
382 if custom_constructors:
383 extended_attributes['CustomConstructors'] = custom_constructors
384
385 return extended_attributes
386
387
388 def extended_attributes_to_constructors(extended_attributes):
389 """Returns constructors and custom_constructors (lists of IdlOperations),
390 deletes the special list attributes, and puts dummy empty value in
391 Constructor and CustomConstructor extended attributes.
392 Auxiliary function for interface_node_to_idl_interface."""
393 constructors = []
394 custom_constructors = []
395 if 'Constructors' in extended_attributes:
396 constructor_list = extended_attributes['Constructors']
397 # If not overloaded, have index 0, otherwise index from 1
398 overloaded_index = 0 if len(constructor_list) == 1 else 1
399 for arguments_node in constructor_list:
400 name = 'Constructor'
401 arguments = arguments_node_to_arguments(arguments_node)
402 constructor = IdlOperation(name=name, extended_attributes=extended_a ttributes, overloaded_index=overloaded_index, arguments=arguments)
403 constructors.append(constructor)
404 overloaded_index += 1
405 del extended_attributes['Constructors']
406 extended_attributes['Constructor'] = None
haraken 2013/07/17 02:44:49 You can use clear_constructor_attributes().
Nils Barth (inactive) 2013/07/17 12:05:09 Done. (As above.)
407
408 # Prefix 'CallWith' and 'RaisesException' with 'Constructor'
409 # FIXME: I have no idea why this is necessary.
haraken 2013/07/17 02:44:49 Yeah, I don't understand why either. We shouldn't
Nils Barth (inactive) 2013/07/17 12:05:09 Got it - thanks for the explanation! Added FIXME.
410 if 'CallWith' in extended_attributes:
411 extended_attributes['ConstructorCallWith'] = extended_attributes['Ca llWith']
412 del extended_attributes['CallWith']
413 if 'RaisesException' in extended_attributes:
414 extended_attributes['ConstructorRaisesException'] = extended_attribu tes['RaisesException']
415 del extended_attributes['RaisesException']
416
417 if 'CustomConstructors' in extended_attributes:
418 custom_constructor_list = extended_attributes['CustomConstructors']
419 # If not overloaded, have index 0, otherwise index from 1
420 overloaded_index = 0 if len(custom_constructor_list) == 1 else 1
421 for arguments_node in custom_constructor_list:
422 name = 'CustomConstructor'
423 arguments = arguments_node_to_arguments(arguments_node)
424 custom_constructor = IdlOperation(name=name, extended_attributes=ext ended_attributes, overloaded_index=overloaded_index, arguments=arguments)
425 custom_constructors.append(custom_constructor)
426 overloaded_index += 1
427 del extended_attributes['CustomConstructors']
428 extended_attributes['CustomConstructor'] = None
haraken 2013/07/17 02:44:49 You can use clear_constructor_attributes().
Nils Barth (inactive) 2013/07/17 12:05:09 Done. (As above.)
429
430 if 'NamedConstructor' in extended_attributes:
431 name = 'NamedConstructor'
432 call_node = extended_attributes['NamedConstructor']
433 extended_attributes['NamedConstructor'] = call_node.GetName()
434 overloaded_index = None # named constructors are not overloaded
435 arguments_node = call_node.GetChildren()[0]
haraken 2013/07/17 02:44:49 Do you want to check that len(children) > 0 ?
Nils Barth (inactive) 2013/07/17 12:05:09 Done.
436 arguments = arguments_node_to_arguments(arguments_node)
437 named_constructor = IdlOperation(name=name, extended_attributes=extended _attributes, overloaded_index=overloaded_index, arguments=arguments)
438 constructors.append(named_constructor)
439
440 return constructors, custom_constructors
441
442
443 def clear_constructor_attributes(extended_attributes):
444 if 'Constructors' in extended_attributes:
445 del extended_attributes['Constructors']
haraken 2013/07/17 02:44:49 This del won't be needed, because you're setting N
Nils Barth (inactive) 2013/07/17 12:05:09 It deletes the plural Constructor*s* and sets the
446 extended_attributes['Constructor'] = None
haraken 2013/07/17 05:43:11 If you set None, I'm afraid that we cannot disting
Nils Barth (inactive) 2013/07/17 12:05:09 The keys of extended_attributes are the names of t
447 if 'CustomConstructors' in extended_attributes:
448 del extended_attributes['CustomConstructors']
haraken 2013/07/17 02:44:49 Ditto.
Nils Barth (inactive) 2013/07/17 12:05:09 Ditto.
449 extended_attributes['CustomConstructor'] = None
450
451
452 # Types
453
454
455 def type_node_to_type(node):
456 children = node.GetChildren()
457 if not children:
haraken 2013/07/17 02:44:49 Instead, you can check that len(children) > 0
Nils Barth (inactive) 2013/07/17 12:05:09 In general “if not some_list:” is considered more
458 raise ValueError('Type node expects children, got none.')
459 if len(children) > 2:
460 raise ValueError('Type node expects at most 2 children (type + optional array []), got %s (multi-dimensional arrays are not supported).' % len(children) )
461
462 type_node_child = children[0]
463 data_type = type_node_inner_to_type(type_node_child)
464
465 if len(children) == 2:
466 array_node = children[1]
467 array_node_class = array_node.GetClass()
468 if array_node_class != 'Array':
469 raise ValueError('Expected Array node as TypeSuffix, got %s node.' % array_node_class)
470 data_type += '[]'
471
472 return data_type
473
474
475 def type_node_inner_to_type(node):
476 """Auxiliary."""
haraken 2013/07/17 02:44:49 I'd remove this comment.
Nils Barth (inactive) 2013/07/17 12:05:09 Good point; not the world’s most useful comment.
477 node_class = node.GetClass()
478 if node_class in ['PrimitiveType', 'Typeref']:
479 return node.GetName()
480 elif node_class == 'Any':
481 return 'any'
482 elif node_class == 'Sequence':
483 return sequence_node_to_type(node)
484 elif node_class == 'UnionType':
485 return union_type_node_to_idl_union_type(node)
486 raise ValueError('Unrecognized node class: %s' % node_class)
487
488
489 def sequence_node_to_type(node):
490 children = node.GetChildren()
491 if len(children) != 1:
492 raise ValueError('Sequence node expects exactly 1 child, got %s' % len(c hildren))
493 sequence_child = children[0]
494 sequence_child_class = sequence_child.GetClass()
495 if sequence_child_class != 'Type':
496 raise ValueError('Unrecognized node class: %s' % sequence_child_class)
497 sequence_type = type_node_to_type(sequence_child)
498 return 'sequence<%s>' % sequence_type
499
500
501 def union_type_node_to_idl_union_type(node):
502 union_member_types = []
503 for member_type_node in node.GetChildren():
504 member_type = type_node_inner_to_type(member_type_node)
505 union_member_types.append(member_type)
506 return IdlUnionType(union_member_types=union_member_types)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698