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