| 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 import os | |
| 32 | |
| 33 from idl_definitions import IdlDefinitions, IdlInterface, IdlException, IdlOpera
tion, IdlCallbackFunction, IdlArgument, IdlAttribute, IdlConstant, IdlEnum, IdlU
nionType | |
| 34 | |
| 35 SPECIAL_KEYWORD_LIST = ['GETTER', 'SETTER', 'DELETER'] | |
| 36 STANDARD_TYPEDEFS = { | |
| 37 # http://www.w3.org/TR/WebIDL/#common-DOMTimeStamp | |
| 38 'DOMTimeStamp': 'unsigned long long', | |
| 39 } | |
| 40 | |
| 41 | |
| 42 def build_idl_definitions_from_ast(node): | |
| 43 if node is None: | |
| 44 return None | |
| 45 node_class = node.GetClass() | |
| 46 if node_class != 'File': | |
| 47 raise ValueError('Unrecognized node class: %s' % node_class) | |
| 48 return file_node_to_idl_definitions(node) | |
| 49 | |
| 50 | |
| 51 def file_node_to_idl_definitions(node): | |
| 52 callback_functions = {} | |
| 53 enumerations = {} | |
| 54 interfaces = {} | |
| 55 typedefs = STANDARD_TYPEDEFS | |
| 56 | |
| 57 children = node.GetChildren() | |
| 58 for child in children: | |
| 59 child_class = child.GetClass() | |
| 60 if child_class == 'Interface': | |
| 61 interface = interface_node_to_idl_interface(child) | |
| 62 interfaces[interface.name] = interface | |
| 63 elif child_class == 'Exception': | |
| 64 exception = exception_node_to_idl_exception(child) | |
| 65 # For simplicity, treat exceptions as interfaces | |
| 66 interfaces[exception.name] = exception | |
| 67 elif child_class == 'Typedef': | |
| 68 type_name = child.GetName() | |
| 69 typedefs[type_name] = typedef_node_to_type(child) | |
| 70 elif child_class == 'Enum': | |
| 71 enumeration = enum_node_to_idl_enum(child) | |
| 72 enumerations[enumeration.name] = enumeration | |
| 73 elif child_class == 'Callback': | |
| 74 callback_function = callback_node_to_idl_callback_function(child) | |
| 75 callback_functions[callback_function.name] = callback_function | |
| 76 elif child_class == 'Implements': | |
| 77 # Implements is handled at the interface merging step | |
| 78 pass | |
| 79 else: | |
| 80 raise ValueError('Unrecognized node class: %s' % child_class) | |
| 81 | |
| 82 return IdlDefinitions(callback_functions=callback_functions, enumerations=en
umerations, interfaces=interfaces, typedefs=typedefs) | |
| 83 | |
| 84 # Constructors for Interface definitions and interface members | |
| 85 | |
| 86 | |
| 87 def interface_node_to_idl_interface(node): | |
| 88 attributes = [] | |
| 89 constants = [] | |
| 90 constructors = None | |
| 91 custom_constructors = None | |
| 92 extended_attributes = None | |
| 93 operations = [] | |
| 94 is_callback = node.GetProperty('CALLBACK') or False | |
| 95 # FIXME: uppercase 'Partial' => 'PARTIAL' in base IDL parser | |
| 96 is_partial = node.GetProperty('Partial') or False | |
| 97 name = node.GetName() | |
| 98 parent = None | |
| 99 | |
| 100 children = node.GetChildren() | |
| 101 for child in children: | |
| 102 child_class = child.GetClass() | |
| 103 if child_class == 'Attribute': | |
| 104 attributes.append(attribute_node_to_idl_attribute(child)) | |
| 105 elif child_class == 'Const': | |
| 106 constants.append(constant_node_to_idl_constant(child)) | |
| 107 elif child_class == 'ExtAttributes': | |
| 108 extended_attributes = ext_attributes_node_to_extended_attributes(chi
ld) | |
| 109 constructors, custom_constructors = extended_attributes_to_construct
ors(extended_attributes) | |
| 110 clear_constructor_attributes(extended_attributes) | |
| 111 elif child_class == 'Operation': | |
| 112 operations.append(operation_node_to_idl_operation(child)) | |
| 113 elif child_class == 'Inherit': | |
| 114 parent = child.GetName() | |
| 115 else: | |
| 116 raise ValueError('Unrecognized node class: %s' % child_class) | |
| 117 | |
| 118 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) | |
| 119 | |
| 120 | |
| 121 def attribute_node_to_idl_attribute(node): | |
| 122 idl_type = None | |
| 123 extended_attributes = {} | |
| 124 is_nullable = False | |
| 125 is_read_only = node.GetProperty('READONLY') or False | |
| 126 is_static = node.GetProperty('STATIC') or False | |
| 127 name = node.GetName() | |
| 128 | |
| 129 children = node.GetChildren() | |
| 130 for child in children: | |
| 131 child_class = child.GetClass() | |
| 132 if child_class == 'Type': | |
| 133 idl_type = type_node_to_type(child) | |
| 134 is_nullable = child.GetProperty('NULLABLE') or False | |
| 135 elif child_class == 'ExtAttributes': | |
| 136 extended_attributes = ext_attributes_node_to_extended_attributes(chi
ld) | |
| 137 else: | |
| 138 raise ValueError('Unrecognized node class: %s' % child_class) | |
| 139 | |
| 140 return IdlAttribute(idl_type=idl_type, extended_attributes=extended_attribut
es, is_nullable=is_nullable, is_read_only=is_read_only, is_static=is_static, nam
e=name) | |
| 141 | |
| 142 | |
| 143 def constant_node_to_idl_constant(node): | |
| 144 name = node.GetName() | |
| 145 | |
| 146 children = node.GetChildren() | |
| 147 num_children = len(children) | |
| 148 if num_children < 2 or num_children > 3: | |
| 149 raise ValueError('Expected 2 or 3 children, got %s' % num_children) | |
| 150 | |
| 151 type_node = children[0] | |
| 152 # ConstType is more limited than Type, so subtree is smaller and we don't | |
| 153 # use the full type_node_to_type function. | |
| 154 idl_type = type_node_inner_to_type(type_node) | |
| 155 | |
| 156 value_node = children[1] | |
| 157 value_node_class = value_node.GetClass() | |
| 158 if value_node_class != 'Value': | |
| 159 raise ValueError('Expected Value node, got %s' % value_node_class) | |
| 160 value = value_node.GetName() | |
| 161 | |
| 162 extended_attributes = None | |
| 163 if num_children == 3: | |
| 164 ext_attributes_node = children[2] | |
| 165 extended_attributes = ext_attributes_node_to_extended_attributes(ext_att
ributes_node) | |
| 166 | |
| 167 return IdlConstant(idl_type=idl_type, extended_attributes=extended_attribute
s, name=name, value=value) | |
| 168 | |
| 169 | |
| 170 def operation_node_to_idl_operation(node): | |
| 171 name = node.GetName() | |
| 172 # FIXME: AST should use None internally | |
| 173 if name == '_unnamed_': | |
| 174 name = None | |
| 175 | |
| 176 is_static = node.GetProperty('STATIC') or False | |
| 177 specials = [] | |
| 178 property_dictionary = node.GetProperties() | |
| 179 for special_keyword in SPECIAL_KEYWORD_LIST: | |
| 180 if special_keyword in property_dictionary: | |
| 181 specials.append(special_keyword.lower()) | |
| 182 | |
| 183 extended_attributes = None | |
| 184 arguments = [] | |
| 185 return_type = None | |
| 186 children = node.GetChildren() | |
| 187 for child in children: | |
| 188 child_class = child.GetClass() | |
| 189 if child_class == 'Arguments': | |
| 190 arguments = arguments_node_to_arguments(child) | |
| 191 elif child_class == 'Type': | |
| 192 return_type = type_node_to_type(child) | |
| 193 elif child_class == 'ExtAttributes': | |
| 194 extended_attributes = ext_attributes_node_to_extended_attributes(chi
ld) | |
| 195 else: | |
| 196 raise ValueError('Unrecognized node class: %s' % child_class) | |
| 197 | |
| 198 return IdlOperation(name=name, idl_type=return_type, extended_attributes=ext
ended_attributes, is_static=is_static, arguments=arguments, specials=specials) | |
| 199 | |
| 200 | |
| 201 def arguments_node_to_arguments(node): | |
| 202 # [Constructor] and [CustomConstructor] without arguments (the bare form) | |
| 203 # have None instead of an arguments node, but have the same meaning as using | |
| 204 # an empty argument list, [Constructor()], so special-case this. | |
| 205 # http://www.w3.org/TR/WebIDL/#Constructor | |
| 206 if node is None: | |
| 207 return [] | |
| 208 arguments = [] | |
| 209 argument_node_list = node.GetChildren() | |
| 210 for argument_node in argument_node_list: | |
| 211 arguments.append(argument_node_to_idl_argument(argument_node)) | |
| 212 return arguments | |
| 213 | |
| 214 | |
| 215 def argument_node_to_idl_argument(node): | |
| 216 name = node.GetName() | |
| 217 | |
| 218 idl_type = None | |
| 219 extended_attributes = {} | |
| 220 is_nullable = False | |
| 221 is_optional = node.GetProperty('OPTIONAL') | |
| 222 is_variadic = False | |
| 223 children = node.GetChildren() | |
| 224 for child in children: | |
| 225 child_class = child.GetClass() | |
| 226 if child_class == 'Type': | |
| 227 idl_type = type_node_to_type(child) | |
| 228 # FIXME: Doesn't handle nullable arrays (Foo[]?), and arrays of | |
| 229 # nullable (Foo?[]) are treated as nullable arrays. No actual use. | |
| 230 is_nullable = child.GetProperty('NULLABLE') | |
| 231 elif child_class == 'ExtAttributes': | |
| 232 extended_attributes = ext_attributes_node_to_extended_attributes(chi
ld) | |
| 233 elif child_class == 'Argument': | |
| 234 child_name = child.GetName() | |
| 235 if child_name != '...': | |
| 236 raise ValueError('Unrecognized Argument node; expected "...", go
t "%s"' % child_name) | |
| 237 is_variadic = child.GetProperty('ELLIPSIS') or False | |
| 238 else: | |
| 239 raise ValueError('Unrecognized node class: %s' % child_class) | |
| 240 | |
| 241 return IdlArgument(name=name, idl_type=idl_type, extended_attributes=extende
d_attributes, is_nullable=is_nullable, is_optional=is_optional, is_variadic=is_v
ariadic) | |
| 242 | |
| 243 # Constructors for for non-interface definitions | |
| 244 | |
| 245 | |
| 246 def callback_node_to_idl_callback_function(node): | |
| 247 name = node.GetName() | |
| 248 children = node.GetChildren() | |
| 249 num_children = len(children) | |
| 250 if num_children != 2: | |
| 251 raise ValueError('Expected 2 children, got %s' % num_children) | |
| 252 | |
| 253 type_node = children[0] | |
| 254 idl_type = type_node_to_type(type_node) | |
| 255 | |
| 256 arguments_node = children[1] | |
| 257 arguments_node_class = arguments_node.GetClass() | |
| 258 if arguments_node_class != 'Arguments': | |
| 259 raise ValueError('Expected Value node, got %s' % arguments_node_class) | |
| 260 arguments = arguments_node_to_arguments(arguments_node) | |
| 261 | |
| 262 return IdlCallbackFunction(name=name, idl_type=idl_type, arguments=arguments
) | |
| 263 | |
| 264 | |
| 265 def enum_node_to_idl_enum(node): | |
| 266 name = node.GetName() | |
| 267 values = [] | |
| 268 for child in node.GetChildren(): | |
| 269 values.append(child.GetName()) | |
| 270 return IdlEnum(name=name, values=values) | |
| 271 | |
| 272 | |
| 273 def exception_operation_node_to_idl_operation(node): | |
| 274 # Needed to handle one case in DOMException.idl: | |
| 275 # // Override in a Mozilla compatible format | |
| 276 # [NotEnumerable] DOMString toString(); | |
| 277 # FIXME: can we remove this? replace with a stringifier? | |
| 278 extended_attributes = {} | |
| 279 name = node.GetName() | |
| 280 children = node.GetChildren() | |
| 281 if len(children) < 1 or len(children) > 2: | |
| 282 raise ValueError('ExceptionOperation node with %s children, expected 1 o
r 2' % len(children)) | |
| 283 | |
| 284 type_node = children[0] | |
| 285 return_type = type_node_to_type(type_node) | |
| 286 | |
| 287 if len(children) > 1: | |
| 288 ext_attributes_node = children[1] | |
| 289 extended_attributes = ext_attributes_node_to_extended_attributes(ext_att
ributes_node) | |
| 290 | |
| 291 return IdlOperation(name=name, idl_type=return_type, extended_attributes=ext
ended_attributes) | |
| 292 | |
| 293 | |
| 294 def exception_node_to_idl_exception(node): | |
| 295 # Exceptions are similar to Interfaces, but simpler | |
| 296 attributes = [] | |
| 297 constants = [] | |
| 298 extended_attributes = None | |
| 299 operations = [] | |
| 300 name = node.GetName() | |
| 301 | |
| 302 children = node.GetChildren() | |
| 303 for child in children: | |
| 304 child_class = child.GetClass() | |
| 305 if child_class == 'Attribute': | |
| 306 attribute = attribute_node_to_idl_attribute(child) | |
| 307 attributes.append(attribute) | |
| 308 elif child_class == 'Const': | |
| 309 constants.append(constant_node_to_idl_constant(child)) | |
| 310 elif child_class == 'ExtAttributes': | |
| 311 extended_attributes = ext_attributes_node_to_extended_attributes(chi
ld) | |
| 312 elif child_class == 'ExceptionOperation': | |
| 313 operations.append(exception_operation_node_to_idl_operation(child)) | |
| 314 else: | |
| 315 raise ValueError('Unrecognized node class: %s' % child_class) | |
| 316 | |
| 317 return IdlException(name=name, attributes=attributes, constants=constants, e
xtended_attributes=extended_attributes, operations=operations) | |
| 318 | |
| 319 | |
| 320 def typedef_node_to_type(node): | |
| 321 children = node.GetChildren() | |
| 322 if len(children) != 1: | |
| 323 raise ValueError('Typedef node with %s children, expected 1' % len(child
ren)) | |
| 324 child = children[0] | |
| 325 child_class = child.GetClass() | |
| 326 if child_class != 'Type': | |
| 327 raise ValueError('Unrecognized node class: %s' % child_class) | |
| 328 return type_node_to_type(child) | |
| 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: move Constructor logic into separate function, instead of modifying | |
| 352 # extended attributes in-place. | |
| 353 constructors = [] | |
| 354 custom_constructors = [] | |
| 355 extended_attributes = {} | |
| 356 | |
| 357 def child_node(extended_attribute_node): | |
| 358 children = extended_attribute_node.GetChildren() | |
| 359 if not children: | |
| 360 return None | |
| 361 if len(children) > 1: | |
| 362 raise ValueError('ExtAttributes node with %s children, expected at m
ost 1' % len(children)) | |
| 363 return children[0] | |
| 364 | |
| 365 extended_attribute_node_list = node.GetChildren() | |
| 366 for extended_attribute_node in extended_attribute_node_list: | |
| 367 name = extended_attribute_node.GetName() | |
| 368 child = child_node(extended_attribute_node) | |
| 369 child_class = child and child.GetClass() | |
| 370 if name == 'Constructor': | |
| 371 if child_class and child_class != 'Arguments': | |
| 372 raise ValueError('Constructor only supports Arguments as child,
but has child of class: %s' % child_class) | |
| 373 constructors.append(child) | |
| 374 elif name == 'CustomConstructor': | |
| 375 if child_class and child_class != 'Arguments': | |
| 376 raise ValueError('[CustomConstructor] only supports Arguments as
child, but has child of class: %s' % child_class) | |
| 377 custom_constructors.append(child) | |
| 378 elif name == 'NamedConstructor': | |
| 379 if child_class and child_class != 'Call': | |
| 380 raise ValueError('[NamedConstructor] only supports Call as child
, but has child of class: %s' % child_class) | |
| 381 extended_attributes[name] = child | |
| 382 elif name == 'SetWrapperReferenceTo': | |
| 383 if not child: | |
| 384 raise ValueError('[SetWrapperReferenceTo] requires a child, but
has none.') | |
| 385 if child_class != 'Arguments': | |
| 386 raise ValueError('[SetWrapperReferenceTo] only supports Argument
s as child, but has child of class: %s' % child_class) | |
| 387 extended_attributes[name] = arguments_node_to_arguments(child) | |
| 388 elif child: | |
| 389 raise ValueError('ExtAttributes node with unexpected children: %s' %
name) | |
| 390 else: | |
| 391 value = extended_attribute_node.GetProperty('VALUE') | |
| 392 extended_attributes[name] = value | |
| 393 | |
| 394 # Store constructors and custom constructors in special list attributes, | |
| 395 # which are deleted later. Note plural in key. | |
| 396 if constructors: | |
| 397 extended_attributes['Constructors'] = constructors | |
| 398 if custom_constructors: | |
| 399 extended_attributes['CustomConstructors'] = custom_constructors | |
| 400 | |
| 401 return extended_attributes | |
| 402 | |
| 403 | |
| 404 def extended_attributes_to_constructors(extended_attributes): | |
| 405 """Returns constructors and custom_constructors (lists of IdlOperations). | |
| 406 | |
| 407 Auxiliary function for interface_node_to_idl_interface. | |
| 408 """ | |
| 409 constructors = [] | |
| 410 custom_constructors = [] | |
| 411 if 'Constructors' in extended_attributes: | |
| 412 constructor_list = extended_attributes['Constructors'] | |
| 413 # If not overloaded, have index 0, otherwise index from 1 | |
| 414 overloaded_index = 0 if len(constructor_list) == 1 else 1 | |
| 415 for arguments_node in constructor_list: | |
| 416 name = 'Constructor' | |
| 417 arguments = arguments_node_to_arguments(arguments_node) | |
| 418 constructor = IdlOperation(name=name, extended_attributes=extended_a
ttributes, overloaded_index=overloaded_index, arguments=arguments) | |
| 419 constructors.append(constructor) | |
| 420 overloaded_index += 1 | |
| 421 | |
| 422 if 'CustomConstructors' in extended_attributes: | |
| 423 custom_constructor_list = extended_attributes['CustomConstructors'] | |
| 424 # If not overloaded, have index 0, otherwise index from 1 | |
| 425 overloaded_index = 0 if len(custom_constructor_list) == 1 else 1 | |
| 426 for arguments_node in custom_constructor_list: | |
| 427 name = 'CustomConstructor' | |
| 428 arguments = arguments_node_to_arguments(arguments_node) | |
| 429 custom_constructor = IdlOperation(name=name, extended_attributes=ext
ended_attributes, overloaded_index=overloaded_index, arguments=arguments) | |
| 430 custom_constructors.append(custom_constructor) | |
| 431 overloaded_index += 1 | |
| 432 | |
| 433 if 'NamedConstructor' in extended_attributes: | |
| 434 name = 'NamedConstructor' | |
| 435 call_node = extended_attributes['NamedConstructor'] | |
| 436 extended_attributes['NamedConstructor'] = call_node.GetName() | |
| 437 overloaded_index = None # named constructors are not overloaded | |
| 438 children = call_node.GetChildren() | |
| 439 if len(children) != 1: | |
| 440 raise ValueError('NamedConstructor node expects 1 child, got %s.' %
len(children)) | |
| 441 arguments_node = children[0] | |
| 442 arguments = arguments_node_to_arguments(arguments_node) | |
| 443 named_constructor = IdlOperation(name=name, extended_attributes=extended
_attributes, overloaded_index=overloaded_index, arguments=arguments) | |
| 444 # FIXME: should return named_constructor separately; appended for Perl | |
| 445 constructors.append(named_constructor) | |
| 446 | |
| 447 return constructors, custom_constructors | |
| 448 | |
| 449 | |
| 450 def clear_constructor_attributes(extended_attributes): | |
| 451 # Deletes Constructor*s* (plural), sets Constructor (singular) | |
| 452 if 'Constructors' in extended_attributes: | |
| 453 del extended_attributes['Constructors'] | |
| 454 extended_attributes['Constructor'] = None | |
| 455 if 'CustomConstructors' in extended_attributes: | |
| 456 del extended_attributes['CustomConstructors'] | |
| 457 extended_attributes['CustomConstructor'] = None | |
| 458 | |
| 459 | |
| 460 # Types | |
| 461 | |
| 462 | |
| 463 def type_node_to_type(node): | |
| 464 children = node.GetChildren() | |
| 465 if len(children) < 1 or len(children) > 2: | |
| 466 raise ValueError('Type node expects 1 or 2 children (type + optional arr
ay []), got %s (multi-dimensional arrays are not supported).' % len(children)) | |
| 467 | |
| 468 type_node_child = children[0] | |
| 469 idl_type = type_node_inner_to_type(type_node_child) | |
| 470 | |
| 471 if len(children) == 2: | |
| 472 array_node = children[1] | |
| 473 array_node_class = array_node.GetClass() | |
| 474 if array_node_class != 'Array': | |
| 475 raise ValueError('Expected Array node as TypeSuffix, got %s node.' %
array_node_class) | |
| 476 idl_type += '[]' | |
| 477 | |
| 478 return idl_type | |
| 479 | |
| 480 | |
| 481 def type_node_inner_to_type(node): | |
| 482 node_class = node.GetClass() | |
| 483 # Note Type*r*ef, not Typedef, meaning the type is an identifier, thus | |
| 484 # either a typedef shorthand (but not a Typedef declaration itself) or an | |
| 485 # interface type. We do not distinguish these, and just use the type name. | |
| 486 if node_class in ['PrimitiveType', 'Typeref']: | |
| 487 return node.GetName() | |
| 488 elif node_class == 'Any': | |
| 489 return 'any' | |
| 490 elif node_class == 'Sequence': | |
| 491 return sequence_node_to_type(node) | |
| 492 elif node_class == 'UnionType': | |
| 493 return union_type_node_to_idl_union_type(node) | |
| 494 raise ValueError('Unrecognized node class: %s' % node_class) | |
| 495 | |
| 496 | |
| 497 def sequence_node_to_type(node): | |
| 498 children = node.GetChildren() | |
| 499 if len(children) != 1: | |
| 500 raise ValueError('Sequence node expects exactly 1 child, got %s' % len(c
hildren)) | |
| 501 sequence_child = children[0] | |
| 502 sequence_child_class = sequence_child.GetClass() | |
| 503 if sequence_child_class != 'Type': | |
| 504 raise ValueError('Unrecognized node class: %s' % sequence_child_class) | |
| 505 sequence_type = type_node_to_type(sequence_child) | |
| 506 return 'sequence<%s>' % sequence_type | |
| 507 | |
| 508 | |
| 509 def union_type_node_to_idl_union_type(node): | |
| 510 union_member_types = [] | |
| 511 for member_type_node in node.GetChildren(): | |
| 512 member_type = type_node_to_type(member_type_node) | |
| 513 union_member_types.append(member_type) | |
| 514 return IdlUnionType(union_member_types=union_member_types) | |
| OLD | NEW |