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 build_idl_definitions_from_ast(node): |
| 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 # Constructors for Interface definitions and interface members |
| 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 |
| 88 operations = [] |
| 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 operations.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, operations=operations, is_callback=is_callback, is_p
artial=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 # ConstType is more limited than Type, so subtree is smaller and we don't |
| 152 # use the full type_node_to_type function. |
| 153 data_type = type_node_inner_to_type(type_node) |
| 154 |
| 155 value_node = children[1] |
| 156 value_node_class = value_node.GetClass() |
| 157 if value_node_class != 'Value': |
| 158 raise ValueError('Expected Value node, got %s' % value_node_class) |
| 159 value = value_node.GetName() |
| 160 |
| 161 extended_attributes = None |
| 162 if num_children == 3: |
| 163 ext_attributes_node = children[2] |
| 164 extended_attributes = ext_attributes_node_to_extended_attributes(ext_att
ributes_node) |
| 165 |
| 166 return IdlConstant(data_type=data_type, extended_attributes=extended_attribu
tes, name=name, value=value) |
| 167 |
| 168 |
| 169 def operation_node_to_idl_operation(node): |
| 170 name = node.GetName() |
| 171 # FIXME: AST should use None internally |
| 172 if name == '_unnamed_': |
| 173 name = None |
| 174 |
| 175 is_static = node.GetProperty('STATIC') or False |
| 176 specials = [] |
| 177 property_dictionary = node.GetProperties() |
| 178 for special_keyword in SPECIAL_KEYWORD_LIST: |
| 179 if special_keyword in property_dictionary: |
| 180 specials.append(special_keyword.lower()) |
| 181 |
| 182 extended_attributes = None |
| 183 arguments = [] |
| 184 return_type = None |
| 185 children = node.GetChildren() |
| 186 for child in children: |
| 187 child_class = child.GetClass() |
| 188 if child_class == 'Arguments': |
| 189 arguments = arguments_node_to_arguments(child) |
| 190 elif child_class == 'Type': |
| 191 return_type = type_node_to_type(child) |
| 192 elif child_class == 'ExtAttributes': |
| 193 extended_attributes = ext_attributes_node_to_extended_attributes(chi
ld) |
| 194 else: |
| 195 raise ValueError('Unrecognized node class: %s' % child_class) |
| 196 |
| 197 return IdlOperation(name=name, data_type=return_type, extended_attributes=ex
tended_attributes, is_static=is_static, arguments=arguments, specials=specials) |
| 198 |
| 199 |
| 200 def arguments_node_to_arguments(node): |
| 201 # [Constructor] and [CustomConstructor] without arguments (the bare form) |
| 202 # have None instead of an arguments node, but have the same meaning as using |
| 203 # an empty argument list, [Constructor()], so special-case this. |
| 204 # http://www.w3.org/TR/WebIDL/#Constructor |
| 205 if node is None: |
| 206 return [] |
| 207 arguments = [] |
| 208 argument_node_list = node.GetChildren() |
| 209 for argument_node in argument_node_list: |
| 210 arguments.append(argument_node_to_idl_argument(argument_node)) |
| 211 return arguments |
| 212 |
| 213 |
| 214 def argument_node_to_idl_argument(node): |
| 215 name = node.GetName() |
| 216 |
| 217 data_type = None |
| 218 extended_attributes = {} |
| 219 # FIXME: Boolean values are inconsistent due to Perl compatibility. |
| 220 # Make all default to False once Perl removed. |
| 221 is_nullable = False |
| 222 is_optional = node.GetProperty('OPTIONAL') |
| 223 is_variadic = None |
| 224 children = node.GetChildren() |
| 225 for child in children: |
| 226 child_class = child.GetClass() |
| 227 if child_class == 'Type': |
| 228 data_type = type_node_to_type(child) |
| 229 is_nullable = child.GetProperty('NULLABLE') |
| 230 elif child_class == 'ExtAttributes': |
| 231 extended_attributes = ext_attributes_node_to_extended_attributes(chi
ld) |
| 232 elif child_class == 'Argument': |
| 233 child_name = child.GetName() |
| 234 if child_name != '...': |
| 235 raise ValueError('Unrecognized Argument node; expected "...", go
t "%s"' % child_name) |
| 236 is_variadic = child.GetProperty('ELLIPSIS') or False |
| 237 else: |
| 238 raise ValueError('Unrecognized node class: %s' % child_class) |
| 239 |
| 240 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) |
| 241 |
| 242 # Constructors for for non-interface definitions |
| 243 |
| 244 |
| 245 def callback_node_to_idl_callback_function(node): |
| 246 name = node.GetName() |
| 247 children = node.GetChildren() |
| 248 num_children = len(children) |
| 249 if num_children != 2: |
| 250 raise ValueError('Expected 2 children, got %s' % num_children) |
| 251 |
| 252 type_node = children[0] |
| 253 data_type = type_node_to_type(type_node) |
| 254 |
| 255 arguments_node = children[1] |
| 256 arguments_node_class = arguments_node.GetClass() |
| 257 if arguments_node_class != 'Arguments': |
| 258 raise ValueError('Expected Value node, got %s' % arguments_node_class) |
| 259 arguments = arguments_node_to_arguments(arguments_node) |
| 260 |
| 261 return IdlCallbackFunction(name=name, data_type=data_type, arguments=argumen
ts) |
| 262 |
| 263 |
| 264 def enum_node_to_idl_enum(node): |
| 265 name = node.GetName() |
| 266 values = [] |
| 267 for child in node.GetChildren(): |
| 268 values.append(child.GetName()) |
| 269 return IdlEnum(name=name, values=values) |
| 270 |
| 271 |
| 272 def exception_operation_node_to_idl_operation(node): |
| 273 # Needed to handle one case in DOMException.idl: |
| 274 # // Override in a Mozilla compatible format |
| 275 # [NotEnumerable] DOMString toString(); |
| 276 # FIXME: can we remove this? replace with a stringifier? |
| 277 extended_attributes = {} |
| 278 name = node.GetName() |
| 279 children = node.GetChildren() |
| 280 if len(children) < 1 or len(children) > 2: |
| 281 raise ValueError('ExceptionOperation node with %s children, expected 1 o
r 2' % len(children)) |
| 282 |
| 283 type_node = children[0] |
| 284 return_type = type_node_to_type(type_node) |
| 285 |
| 286 if len(children) > 1: |
| 287 ext_attributes_node = children[1] |
| 288 extended_attributes = ext_attributes_node_to_extended_attributes(ext_att
ributes_node) |
| 289 |
| 290 return IdlOperation(name=name, data_type=return_type, extended_attributes=ex
tended_attributes) |
| 291 |
| 292 |
| 293 def exception_node_to_idl_exception(node): |
| 294 # Exceptions are similar to Interfaces, but simpler |
| 295 attributes = [] |
| 296 constants = [] |
| 297 extended_attributes = None |
| 298 operations = [] |
| 299 name = node.GetName() |
| 300 |
| 301 children = node.GetChildren() |
| 302 for child in children: |
| 303 child_class = child.GetClass() |
| 304 if child_class == 'Attribute': |
| 305 attribute = attribute_node_to_idl_attribute(child) |
| 306 attributes.append(attribute) |
| 307 elif child_class == 'Const': |
| 308 constants.append(constant_node_to_idl_constant(child)) |
| 309 elif child_class == 'ExtAttributes': |
| 310 extended_attributes = ext_attributes_node_to_extended_attributes(chi
ld) |
| 311 elif child_class == 'ExceptionOperation': |
| 312 operations.append(exception_operation_node_to_idl_operation(child)) |
| 313 else: |
| 314 raise ValueError('Unrecognized node class: %s' % child_class) |
| 315 |
| 316 return IdlException(name=name, attributes=attributes, constants=constants, e
xtended_attributes=extended_attributes, operations=operations) |
| 317 |
| 318 |
| 319 def typedef_node_to_idl_typedef(node): |
| 320 data_type = None |
| 321 extended_attributes = None |
| 322 |
| 323 children = node.GetChildren() |
| 324 for child in children: |
| 325 child_class = child.GetClass() |
| 326 if child_class == 'Type': |
| 327 data_type = type_node_to_type(child) |
| 328 elif child_class == 'ExtAttributes': |
| 329 extended_attributes = ext_attributes_node_to_extended_attributes(chi
ld) |
| 330 raise ValueError('Extended attributes in a typedef are untested!') |
| 331 else: |
| 332 raise ValueError('Unrecognized node class: %s' % child_class) |
| 333 |
| 334 return IdlTypedef(data_type=data_type, extended_attributes=extended_attribut
es) |
| 335 |
| 336 # Extended attributes |
| 337 |
| 338 |
| 339 def ext_attributes_node_to_extended_attributes(node): |
| 340 """ |
| 341 Returns: |
| 342 Dictionary of {ExtAttributeName: ExtAttributeValue}. |
| 343 Value is usually a string, with three exceptions: |
| 344 Constructors: value is a list of Arguments nodes, corresponding to |
| 345 possibly signatures of the constructor. |
| 346 CustomConstructors: value is a list of Arguments nodes, corresponding to |
| 347 possibly signatures of the custom constructor. |
| 348 NamedConstructor: value is a Call node, corresponding to the single |
| 349 signature of the named constructor. |
| 350 """ |
| 351 # Primarily just make a dictionary from the children. |
| 352 # The only complexity is handling various types of constructors: |
| 353 # Constructors and Custom Constructors can have duplicate entries due to |
| 354 # overloading, and thus are stored in temporary lists. |
| 355 # However, Named Constructors cannot be overloaded, and thus do not have |
| 356 # a list. |
| 357 # FIXME: Add overloading for Named Constructors and remove custom bindings |
| 358 # for HTMLImageElement |
| 359 constructors = [] |
| 360 custom_constructors = [] |
| 361 extended_attributes = {} |
| 362 |
| 363 attribute_list = node.GetChildren() |
| 364 for attribute in attribute_list: |
| 365 name = attribute.GetName() |
| 366 children = attribute.GetChildren() |
| 367 if name in ['Constructor', 'CustomConstructor', 'NamedConstructor']: |
| 368 child = None |
| 369 child_class = None |
| 370 if children: |
| 371 if len(children) > 1: |
| 372 raise ValueError('ExtAttributes node with %s children, expec
ted at most 1' % len(children)) |
| 373 child = children[0] |
| 374 child_class = child.GetClass() |
| 375 if name == 'Constructor': |
| 376 if child_class and child_class != 'Arguments': |
| 377 raise ValueError('Constructor only supports Arguments as chi
ld, but has child of class: %s' % child_class) |
| 378 constructors.append(child) |
| 379 elif name == 'CustomConstructor': |
| 380 if child_class and child_class != 'Arguments': |
| 381 raise ValueError('Custom Constructor only supports Arguments
as child, but has child of class: %s' % child_class) |
| 382 custom_constructors.append(child) |
| 383 else: # name == 'NamedConstructor' |
| 384 if child_class and child_class != 'Call': |
| 385 raise ValueError('Named Constructor only supports Call as ch
ild, but has child of class: %s' % child_class) |
| 386 extended_attributes[name] = child |
| 387 elif children: |
| 388 raise ValueError('Non-constructor ExtAttributes node with children:
%s' % name) |
| 389 else: |
| 390 value = attribute.GetProperty('VALUE') |
| 391 extended_attributes[name] = value |
| 392 |
| 393 # Store constructors and custom constructors in special list attributes, |
| 394 # which are deleted later. Note plural in key. |
| 395 if constructors: |
| 396 extended_attributes['Constructors'] = constructors |
| 397 if custom_constructors: |
| 398 extended_attributes['CustomConstructors'] = custom_constructors |
| 399 |
| 400 return extended_attributes |
| 401 |
| 402 |
| 403 def extended_attributes_to_constructors(extended_attributes): |
| 404 """Returns constructors and custom_constructors (lists of IdlOperations). |
| 405 |
| 406 Auxiliary function for interface_node_to_idl_interface. |
| 407 """ |
| 408 constructors = [] |
| 409 custom_constructors = [] |
| 410 if 'Constructors' in extended_attributes: |
| 411 constructor_list = extended_attributes['Constructors'] |
| 412 # If not overloaded, have index 0, otherwise index from 1 |
| 413 overloaded_index = 0 if len(constructor_list) == 1 else 1 |
| 414 for arguments_node in constructor_list: |
| 415 name = 'Constructor' |
| 416 arguments = arguments_node_to_arguments(arguments_node) |
| 417 constructor = IdlOperation(name=name, extended_attributes=extended_a
ttributes, overloaded_index=overloaded_index, arguments=arguments) |
| 418 constructors.append(constructor) |
| 419 overloaded_index += 1 |
| 420 |
| 421 # Prefix 'CallWith' and 'RaisesException' with 'Constructor' |
| 422 # FIXME: Change extended attributes to include prefix explicitly. |
| 423 if 'CallWith' in extended_attributes: |
| 424 extended_attributes['ConstructorCallWith'] = extended_attributes['Ca
llWith'] |
| 425 del extended_attributes['CallWith'] |
| 426 if 'RaisesException' in extended_attributes: |
| 427 extended_attributes['ConstructorRaisesException'] = extended_attribu
tes['RaisesException'] |
| 428 del extended_attributes['RaisesException'] |
| 429 |
| 430 if 'CustomConstructors' in extended_attributes: |
| 431 custom_constructor_list = extended_attributes['CustomConstructors'] |
| 432 # If not overloaded, have index 0, otherwise index from 1 |
| 433 overloaded_index = 0 if len(custom_constructor_list) == 1 else 1 |
| 434 for arguments_node in custom_constructor_list: |
| 435 name = 'CustomConstructor' |
| 436 arguments = arguments_node_to_arguments(arguments_node) |
| 437 custom_constructor = IdlOperation(name=name, extended_attributes=ext
ended_attributes, overloaded_index=overloaded_index, arguments=arguments) |
| 438 custom_constructors.append(custom_constructor) |
| 439 overloaded_index += 1 |
| 440 |
| 441 if 'NamedConstructor' in extended_attributes: |
| 442 name = 'NamedConstructor' |
| 443 call_node = extended_attributes['NamedConstructor'] |
| 444 extended_attributes['NamedConstructor'] = call_node.GetName() |
| 445 overloaded_index = None # named constructors are not overloaded |
| 446 children = call_node.GetChildren() |
| 447 if len(children) != 1: |
| 448 raise ValueError('NamedConstructor node expects 1 child, got %s.' %
len(children)) |
| 449 arguments_node = children[0] |
| 450 arguments = arguments_node_to_arguments(arguments_node) |
| 451 named_constructor = IdlOperation(name=name, extended_attributes=extended
_attributes, overloaded_index=overloaded_index, arguments=arguments) |
| 452 constructors.append(named_constructor) |
| 453 |
| 454 return constructors, custom_constructors |
| 455 |
| 456 |
| 457 def clear_constructor_attributes(extended_attributes): |
| 458 # Deletes Constructor*s* (plural), sets Constructor (singular) |
| 459 if 'Constructors' in extended_attributes: |
| 460 del extended_attributes['Constructors'] |
| 461 extended_attributes['Constructor'] = None |
| 462 if 'CustomConstructors' in extended_attributes: |
| 463 del extended_attributes['CustomConstructors'] |
| 464 extended_attributes['CustomConstructor'] = None |
| 465 |
| 466 |
| 467 # Types |
| 468 |
| 469 |
| 470 def type_node_to_type(node): |
| 471 children = node.GetChildren() |
| 472 if len(children) < 1 or len(children) > 2: |
| 473 raise ValueError('Type node expects 1 or 2 children (type + optional arr
ay []), got %s (multi-dimensional arrays are not supported).' % len(children)) |
| 474 |
| 475 type_node_child = children[0] |
| 476 data_type = type_node_inner_to_type(type_node_child) |
| 477 |
| 478 if len(children) == 2: |
| 479 array_node = children[1] |
| 480 array_node_class = array_node.GetClass() |
| 481 if array_node_class != 'Array': |
| 482 raise ValueError('Expected Array node as TypeSuffix, got %s node.' %
array_node_class) |
| 483 data_type += '[]' |
| 484 |
| 485 return data_type |
| 486 |
| 487 |
| 488 def type_node_inner_to_type(node): |
| 489 node_class = node.GetClass() |
| 490 # FIXME: Typedef is misspelled as Type*r*ef in base parser. |
| 491 if node_class in ['PrimitiveType', 'Typeref']: |
| 492 return node.GetName() |
| 493 elif node_class == 'Any': |
| 494 return 'any' |
| 495 elif node_class == 'Sequence': |
| 496 return sequence_node_to_type(node) |
| 497 elif node_class == 'UnionType': |
| 498 return union_type_node_to_idl_union_type(node) |
| 499 raise ValueError('Unrecognized node class: %s' % node_class) |
| 500 |
| 501 |
| 502 def sequence_node_to_type(node): |
| 503 children = node.GetChildren() |
| 504 if len(children) != 1: |
| 505 raise ValueError('Sequence node expects exactly 1 child, got %s' % len(c
hildren)) |
| 506 sequence_child = children[0] |
| 507 sequence_child_class = sequence_child.GetClass() |
| 508 if sequence_child_class != 'Type': |
| 509 raise ValueError('Unrecognized node class: %s' % sequence_child_class) |
| 510 sequence_type = type_node_to_type(sequence_child) |
| 511 return 'sequence<%s>' % sequence_type |
| 512 |
| 513 |
| 514 def union_type_node_to_idl_union_type(node): |
| 515 union_member_types = [] |
| 516 for member_type_node in node.GetChildren(): |
| 517 member_type = type_node_to_type(member_type_node) |
| 518 union_member_types.append(member_type) |
| 519 return IdlUnionType(union_member_types=union_member_types) |
OLD | NEW |