| 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 |