1d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# Copyright (C) 2013 Google Inc. All rights reserved.
2d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#
3d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# Redistribution and use in source and binary forms, with or without
4d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# modification, are permitted provided that the following conditions are
5d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# met:
6d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#
7d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#     * Redistributions of source code must retain the above copyright
8d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# notice, this list of conditions and the following disclaimer.
9d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#     * Redistributions in binary form must reproduce the above
10d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# copyright notice, this list of conditions and the following disclaimer
11d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# in the documentation and/or other materials provided with the
12d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# distribution.
13d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#     * Neither the name of Google Inc. nor the names of its
14d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# contributors may be used to endorse or promote products derived from
15d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# this software without specific prior written permission.
16d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#
17d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
29d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)"""Blink IDL Intermediate Representation (IR) classes.
30d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
31d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)Classes are primarily constructors, which build an IdlDefinitions object
32d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)(and various contained objects) from an AST (produced by blink_idl_parser).
33d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
34d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)This is in two steps:
35d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)* Constructors walk the AST, creating objects.
36d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)* Typedef resolution.
37d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
38d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)Typedefs are all resolved here, and not stored in IR.
39d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
40d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)Typedef resolution uses some auxiliary classes and OOP techniques to make this
41d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)a generic call, via the resolve_typedefs() method.
42d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
43d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)Class hierarchy (mostly containment, '<' for inheritance):
44d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
45d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)IdlDefinitions
46d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    IdlCallbackFunction < TypedObject
47d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    IdlEnum :: FIXME: remove, just use a dict for enums
48d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    IdlInterface
49d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        IdlAttribute < TypedObject
50d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        IdlConstant < TypedObject
51197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        IdlLiteral
52d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        IdlOperation < TypedObject
53d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            IdlArgument < TypedObject
54197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        IdlStringifier
55d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    IdlException < IdlInterface
56d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        (same contents as IdlInterface)
57d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
58d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)TypedObject :: mixin for typedef resolution
59d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
60d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
61d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)"""
62d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
63d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)import abc
64d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
659e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)from idl_types import IdlType, IdlUnionType, IdlArrayType, IdlSequenceType, IdlNullableType
66d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
67d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)SPECIAL_KEYWORD_LIST = ['GETTER', 'SETTER', 'DELETER']
68d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)STANDARD_TYPEDEFS = {
69d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # http://www.w3.org/TR/WebIDL/#common-DOMTimeStamp
70d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    'DOMTimeStamp': 'unsigned long long',
71d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
72d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
73d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
74d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
75d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# TypedObject (mixin for typedef resolution)
76d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
77d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
78d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)class TypedObject(object):
79d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    """Object with a type, such as an Attribute or Operation (return value).
80d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
81d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    The type can be an actual type, or can be a typedef, which must be resolved
82d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    before passing data to the code generator.
83d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    """
84d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    __metaclass__ = abc.ABCMeta
85d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    idl_type = None
86d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
87d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    def resolve_typedefs(self, typedefs):
88d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        """Resolve typedefs to actual types in the object."""
89d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # Constructors don't have their own return type, because it's the
90d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # interface itself.
91d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if not self.idl_type:
92d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return
93d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # Need to re-assign self.idl_type, not just mutate idl_type,
94d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # since type(idl_type) may change.
95d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.idl_type = self.idl_type.resolve_typedefs(typedefs)
96d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
97d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
98d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
99d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# Definitions (main container class)
100d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
101d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
102d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)class IdlDefinitions(object):
103e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    def __init__(self, idl_name, node):
104d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        """Args: node: AST root node, class == 'File'"""
105d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.callback_functions = {}
106f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        self.dictionaries = {}
107d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.enumerations = {}
108d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.interfaces = {}
109e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        self.idl_name = idl_name
110d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
111d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        node_class = node.GetClass()
112d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if node_class != 'File':
113d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            raise ValueError('Unrecognized node class: %s' % node_class)
114d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
115d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        typedefs = dict((typedef_name, IdlType(type_name))
116d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        for typedef_name, type_name in
117d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                        STANDARD_TYPEDEFS.iteritems())
118d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
119d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        children = node.GetChildren()
120d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for child in children:
121d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            child_class = child.GetClass()
122d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if child_class == 'Interface':
123e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                interface = IdlInterface(idl_name, child)
124d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                self.interfaces[interface.name] = interface
125d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            elif child_class == 'Exception':
126e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                exception = IdlException(idl_name, child)
127d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                # For simplicity, treat exceptions as interfaces
128d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                self.interfaces[exception.name] = exception
129d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            elif child_class == 'Typedef':
130d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                type_name = child.GetName()
131d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                typedefs[type_name] = typedef_node_to_type(child)
132d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            elif child_class == 'Enum':
133e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                enumeration = IdlEnum(idl_name, child)
134d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                self.enumerations[enumeration.name] = enumeration
135d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            elif child_class == 'Callback':
136e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                callback_function = IdlCallbackFunction(idl_name, child)
137d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                self.callback_functions[callback_function.name] = callback_function
138d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            elif child_class == 'Implements':
139d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                # Implements is handled at the interface merging step
140d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                pass
141f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            elif child_class == 'Dictionary':
142e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                dictionary = IdlDictionary(idl_name, child)
143f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu                self.dictionaries[dictionary.name] = dictionary
144d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            else:
145d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                raise ValueError('Unrecognized node class: %s' % child_class)
146d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
147d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # Typedefs are not stored in IR:
148d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # Resolve typedefs with the actual types and then discard the Typedefs.
149d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # http://www.w3.org/TR/WebIDL/#idl-typedefs
150d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.resolve_typedefs(typedefs)
151d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
152d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    def resolve_typedefs(self, typedefs):
153d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for callback_function in self.callback_functions.itervalues():
154d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            callback_function.resolve_typedefs(typedefs)
155d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for interface in self.interfaces.itervalues():
156d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            interface.resolve_typedefs(typedefs)
157d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
15843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    def update(self, other):
15943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        """Update with additional IdlDefinitions."""
16043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        for interface_name, new_interface in other.interfaces.iteritems():
16143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)            if not new_interface.is_partial:
16243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)                # Add as new interface
16343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)                self.interfaces[interface_name] = new_interface
16443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)                continue
16543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)
16643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)            # Merge partial to existing interface
16743e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)            try:
16843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)                self.interfaces[interface_name].merge(new_interface)
16943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)            except KeyError:
17043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)                raise Exception('Tried to merge partial interface for {0}, '
17143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)                                'but no existing interface by that name'
17243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)                                .format(interface_name))
17343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)
17407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            # Merge callbacks and enumerations
17507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            self.enumerations.update(other.enumerations)
17607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            self.callback_functions.update(other.callback_functions)
17707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
178d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
179d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
180d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# Callback Functions
181d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
182d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
183d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)class IdlCallbackFunction(TypedObject):
184e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    def __init__(self, idl_name, node):
185d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        children = node.GetChildren()
186d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        num_children = len(children)
187d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if num_children != 2:
188d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            raise ValueError('Expected 2 children, got %s' % num_children)
189d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        type_node, arguments_node = children
190d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        arguments_node_class = arguments_node.GetClass()
191d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if arguments_node_class != 'Arguments':
192d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            raise ValueError('Expected Arguments node, got %s' % arguments_node_class)
193d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
194e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        self.idl_name = idl_name
195d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.name = node.GetName()
196d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.idl_type = type_node_to_type(type_node)
197e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        self.arguments = arguments_node_to_arguments(idl_name, arguments_node)
198d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
199d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    def resolve_typedefs(self, typedefs):
200d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        TypedObject.resolve_typedefs(self, typedefs)
201d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for argument in self.arguments:
202d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            argument.resolve_typedefs(typedefs)
203d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
204d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
205d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
206f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu# Dictionary
207f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu################################################################################
208f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
209f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liuclass IdlDictionary(object):
210e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    def __init__(self, idl_name, node):
211c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        self.extended_attributes = {}
212c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        self.is_partial = node.GetProperty('Partial') or False
213e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        self.idl_name = idl_name
214f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        self.name = node.GetName()
215f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        self.members = []
216c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        self.parent = None
217f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        for child in node.GetChildren():
218f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            child_class = child.GetClass()
219f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            if child_class == 'Inherit':
220f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu                self.parent = child.GetName()
221f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            elif child_class == 'Key':
222e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                self.members.append(IdlDictionaryMember(idl_name, child))
223c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            elif child_class == 'ExtAttributes':
224c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                self.extended_attributes = (
225e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                    ext_attributes_node_to_extended_attributes(idl_name, child))
226f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            else:
227f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu                raise ValueError('Unrecognized node class: %s' % child_class)
228f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
229f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
230f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liuclass IdlDictionaryMember(object):
231e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    def __init__(self, idl_name, node):
232f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        self.default_value = None
233f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        self.extended_attributes = {}
234f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        self.idl_type = None
235e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        self.idl_name = idl_name
236f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        self.name = node.GetName()
237f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        for child in node.GetChildren():
238f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            child_class = child.GetClass()
239f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            if child_class == 'Type':
240f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu                self.idl_type = type_node_to_type(child)
241f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            elif child_class == 'Default':
242c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                self.default_value = default_node_to_idl_literal(child)
243f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            elif child_class == 'ExtAttributes':
244c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                self.extended_attributes = (
245e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                    ext_attributes_node_to_extended_attributes(idl_name, child))
246f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            else:
247f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu                raise ValueError('Unrecognized node class: %s' % child_class)
248f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
249f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
250f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu################################################################################
251d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# Enumerations
252d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
253d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
254d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)class IdlEnum(object):
255d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # FIXME: remove, just treat enums as a dictionary
256e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    def __init__(self, idl_name, node):
257e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        self.idl_name = idl_name
258d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.name = node.GetName()
259d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.values = []
260d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for child in node.GetChildren():
261d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            self.values.append(child.GetName())
262d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
263d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
264d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
265d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# Interfaces and Exceptions
266d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
267d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
268d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)class IdlInterface(object):
269e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    def __init__(self, idl_name, node=None):
270d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.attributes = []
271d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.constants = []
272d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.constructors = []
273d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.custom_constructors = []
274d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.extended_attributes = {}
275d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.operations = []
276d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.parent = None
277197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        self.stringifier = None
278d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if not node:  # Early exit for IdlException.__init__
279d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return
280d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
281d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.is_callback = node.GetProperty('CALLBACK') or False
282d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.is_exception = False
283d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # FIXME: uppercase 'Partial' => 'PARTIAL' in base IDL parser
284d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.is_partial = node.GetProperty('Partial') or False
285e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        self.idl_name = idl_name
286d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.name = node.GetName()
287d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
288d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        children = node.GetChildren()
289d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for child in children:
290d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            child_class = child.GetClass()
291d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if child_class == 'Attribute':
292e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                self.attributes.append(IdlAttribute(idl_name, child))
293d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            elif child_class == 'Const':
294e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                self.constants.append(IdlConstant(idl_name, child))
295d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            elif child_class == 'ExtAttributes':
296e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                extended_attributes = ext_attributes_node_to_extended_attributes(idl_name, child)
297d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                self.constructors, self.custom_constructors = (
298e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                    extended_attributes_to_constructors(idl_name, extended_attributes))
299d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                clear_constructor_attributes(extended_attributes)
300d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                self.extended_attributes = extended_attributes
301d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            elif child_class == 'Operation':
302e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                self.operations.append(IdlOperation(idl_name, child))
303d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            elif child_class == 'Inherit':
304d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                self.parent = child.GetName()
305197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            elif child_class == 'Stringifier':
306e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                self.stringifier = IdlStringifier(idl_name, child)
307197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                self.process_stringifier()
308d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            else:
309d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                raise ValueError('Unrecognized node class: %s' % child_class)
310d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
311d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    def resolve_typedefs(self, typedefs):
312d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for attribute in self.attributes:
313d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            attribute.resolve_typedefs(typedefs)
314d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for constant in self.constants:
315d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            constant.resolve_typedefs(typedefs)
316d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for constructor in self.constructors:
317d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            constructor.resolve_typedefs(typedefs)
318d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for custom_constructor in self.custom_constructors:
319d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            custom_constructor.resolve_typedefs(typedefs)
320d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for operation in self.operations:
321d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            operation.resolve_typedefs(typedefs)
322d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
323197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    def process_stringifier(self):
324197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        """Add the stringifier's attribute or named operation child, if it has
325197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        one, as a regular attribute/operation of this interface."""
326197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if self.stringifier.attribute:
327197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            self.attributes.append(self.stringifier.attribute)
328197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        elif self.stringifier.operation:
329197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            self.operations.append(self.stringifier.operation)
330197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
33143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    def merge(self, other):
33243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        """Merge in another interface's members (e.g., partial interface)"""
33343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        self.attributes.extend(other.attributes)
33443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        self.constants.extend(other.constants)
33543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        self.operations.extend(other.operations)
33643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)
337d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
338d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)class IdlException(IdlInterface):
339d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # Properly exceptions and interfaces are distinct, and thus should inherit a
340d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # common base class (say, "IdlExceptionOrInterface").
341d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # However, there is only one exception (DOMException), and new exceptions
342d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # are not expected. Thus it is easier to implement exceptions as a
343d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # restricted subclass of interfaces.
344d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # http://www.w3.org/TR/WebIDL/#idl-exceptions
345e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    def __init__(self, idl_name, node):
346d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # Exceptions are similar to Interfaces, but simpler
347e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        IdlInterface.__init__(self, idl_name)
348d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.is_callback = False
349d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.is_exception = True
350d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.is_partial = False
351e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        self.idl_name = idl_name
352d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.name = node.GetName()
353d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
354d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        children = node.GetChildren()
355d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for child in children:
356d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            child_class = child.GetClass()
357d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if child_class == 'Attribute':
358e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                attribute = IdlAttribute(idl_name, child)
359d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                self.attributes.append(attribute)
360d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            elif child_class == 'Const':
361e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                self.constants.append(IdlConstant(idl_name, child))
362d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            elif child_class == 'ExtAttributes':
363e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                self.extended_attributes = ext_attributes_node_to_extended_attributes(idl_name, child)
364d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            elif child_class == 'ExceptionOperation':
365e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                self.operations.append(IdlOperation.from_exception_operation_node(idl_name, child))
366d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            else:
367d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                raise ValueError('Unrecognized node class: %s' % child_class)
368d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
369d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
370d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
371d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# Attributes
372d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
373d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
374d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)class IdlAttribute(TypedObject):
375e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    def __init__(self, idl_name, node):
376d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.is_read_only = node.GetProperty('READONLY') or False
377d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.is_static = node.GetProperty('STATIC') or False
378e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        self.idl_name = idl_name
379d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.name = node.GetName()
380d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # Defaults, overridden below
381d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.idl_type = None
382d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.extended_attributes = {}
383d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
384d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        children = node.GetChildren()
385d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for child in children:
386d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            child_class = child.GetClass()
387d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if child_class == 'Type':
388d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                self.idl_type = type_node_to_type(child)
389d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            elif child_class == 'ExtAttributes':
390e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                self.extended_attributes = ext_attributes_node_to_extended_attributes(idl_name, child)
391d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            else:
392d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                raise ValueError('Unrecognized node class: %s' % child_class)
393d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
394d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
395d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
396d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# Constants
397d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
398d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
399d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)class IdlConstant(TypedObject):
400e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    def __init__(self, idl_name, node):
401d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        children = node.GetChildren()
402d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        num_children = len(children)
403d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if num_children < 2 or num_children > 3:
404d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            raise ValueError('Expected 2 or 3 children, got %s' % num_children)
405d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        type_node = children[0]
406d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        value_node = children[1]
407d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        value_node_class = value_node.GetClass()
408d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if value_node_class != 'Value':
409d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            raise ValueError('Expected Value node, got %s' % value_node_class)
410d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
411e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        self.idl_name = idl_name
412d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.name = node.GetName()
413d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # ConstType is more limited than Type, so subtree is smaller and
414d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # we don't use the full type_node_to_type function.
415d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.idl_type = type_node_inner_to_type(type_node)
416197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        # FIXME: This code is unnecessarily complicated due to the rather
417197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        # inconsistent way the upstream IDL parser outputs default values.
418197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        # http://crbug.com/374178
419197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if value_node.GetProperty('TYPE') == 'float':
420197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            self.value = value_node.GetProperty('VALUE')
421197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        else:
422197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            self.value = value_node.GetName()
423d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
424d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if num_children == 3:
425d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            ext_attributes_node = children[2]
426e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            self.extended_attributes = ext_attributes_node_to_extended_attributes(idl_name, ext_attributes_node)
427d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        else:
428d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            self.extended_attributes = {}
429d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
430d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
431d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
4325d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)# Literals
4335d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)################################################################################
4345d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
4355d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)class IdlLiteral(object):
4365d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    def __init__(self, idl_type, value):
4375d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        self.idl_type = idl_type
4385d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        self.value = value
4395d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        self.is_null = False
4405d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
4415d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    def __str__(self):
4425d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        if self.idl_type == 'DOMString':
4435d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            return 'String("%s")' % self.value
4445d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        if self.idl_type == 'integer':
4455d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            return '%d' % self.value
4465d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        if self.idl_type == 'float':
4475d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            return '%g' % self.value
4485d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        if self.idl_type == 'boolean':
4495d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            return 'true' if self.value else 'false'
4505d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        raise ValueError('Unsupported literal type: %s' % self.idl_type)
4515d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
4525d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
4535d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)class IdlLiteralNull(IdlLiteral):
4545d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    def __init__(self):
4555d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        self.idl_type = 'NULL'
4565d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        self.value = None
4575d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        self.is_null = True
4585d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
4595d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    def __str__(self):
4605d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        return 'nullptr'
4615d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
4625d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
4635d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)def default_node_to_idl_literal(node):
4645d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    # FIXME: This code is unnecessarily complicated due to the rather
4655d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    # inconsistent way the upstream IDL parser outputs default values.
4665d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    # http://crbug.com/374178
4675d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    idl_type = node.GetProperty('TYPE')
4685d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if idl_type == 'DOMString':
4695d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        value = node.GetProperty('NAME')
4705d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        if '"' in value or '\\' in value:
4715d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            raise ValueError('Unsupported string value: %r' % value)
4725d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        return IdlLiteral(idl_type, value)
4735d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if idl_type == 'integer':
474197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return IdlLiteral(idl_type, int(node.GetProperty('NAME'), base=0))
4755d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if idl_type == 'float':
4765d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        return IdlLiteral(idl_type, float(node.GetProperty('VALUE')))
4775d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if idl_type == 'boolean':
4785d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        return IdlLiteral(idl_type, node.GetProperty('VALUE'))
4795d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if idl_type == 'NULL':
4805d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        return IdlLiteralNull()
4815d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    raise ValueError('Unrecognized default value type: %s' % idl_type)
4825d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
4835d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
4845d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)################################################################################
485d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# Operations
486d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
487d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
488d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)class IdlOperation(TypedObject):
489e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    def __init__(self, idl_name, node=None):
490d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.arguments = []
491d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.extended_attributes = {}
492d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.specials = []
4935d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        self.is_constructor = False
494d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
495d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if not node:
496d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            self.is_static = False
497d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return
498e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        self.idl_name = idl_name
499d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.name = node.GetName()  # FIXME: should just be: or ''
500d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # FIXME: AST should use None internally
501d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if self.name == '_unnamed_':
502d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            self.name = ''
503d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
504d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.is_static = node.GetProperty('STATIC') or False
505d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        property_dictionary = node.GetProperties()
506d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for special_keyword in SPECIAL_KEYWORD_LIST:
507d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if special_keyword in property_dictionary:
508d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                self.specials.append(special_keyword.lower())
509d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
510d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.idl_type = None
511d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        children = node.GetChildren()
512d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for child in children:
513d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            child_class = child.GetClass()
514d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if child_class == 'Arguments':
515e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                self.arguments = arguments_node_to_arguments(idl_name, child)
516d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            elif child_class == 'Type':
517d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                self.idl_type = type_node_to_type(child)
518d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            elif child_class == 'ExtAttributes':
519e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                self.extended_attributes = ext_attributes_node_to_extended_attributes(idl_name, child)
520d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            else:
521d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                raise ValueError('Unrecognized node class: %s' % child_class)
522d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
523d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    @classmethod
524e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    def from_exception_operation_node(cls, idl_name, node):
525d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # Needed to handle one case in DOMException.idl:
526d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # // Override in a Mozilla compatible format
527d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # [NotEnumerable] DOMString toString();
528d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # FIXME: can we remove this? replace with a stringifier?
529e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        operation = cls(idl_name)
530d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        operation.name = node.GetName()
531d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        children = node.GetChildren()
532d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if len(children) < 1 or len(children) > 2:
533d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            raise ValueError('ExceptionOperation node with %s children, expected 1 or 2' % len(children))
534d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
535d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        type_node = children[0]
536d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        operation.idl_type = type_node_to_type(type_node)
537d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
538d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if len(children) > 1:
539d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            ext_attributes_node = children[1]
540e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            operation.extended_attributes = ext_attributes_node_to_extended_attributes(idl_name, ext_attributes_node)
541d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
542d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return operation
543d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
544d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    @classmethod
545e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    def constructor_from_arguments_node(cls, name, idl_name, arguments_node):
546e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        constructor = cls(idl_name)
547d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        constructor.name = name
548e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        constructor.arguments = arguments_node_to_arguments(idl_name, arguments_node)
5495d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        constructor.is_constructor = True
550d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return constructor
551d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
552d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    def resolve_typedefs(self, typedefs):
553d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        TypedObject.resolve_typedefs(self, typedefs)
554d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for argument in self.arguments:
555d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            argument.resolve_typedefs(typedefs)
556d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
557d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
558d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
559d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# Arguments
560d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
561d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
562d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)class IdlArgument(TypedObject):
563e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    def __init__(self, idl_name, node):
564d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.extended_attributes = {}
565d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.idl_type = None
566d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.is_optional = node.GetProperty('OPTIONAL')  # syntax: (optional T)
567d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.is_variadic = False  # syntax: (T...)
568e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        self.idl_name = idl_name
569d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        self.name = node.GetName()
5705d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        self.default_value = None
571d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
572d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        children = node.GetChildren()
573d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for child in children:
574d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            child_class = child.GetClass()
575d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if child_class == 'Type':
576d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                self.idl_type = type_node_to_type(child)
577d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            elif child_class == 'ExtAttributes':
578e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                self.extended_attributes = ext_attributes_node_to_extended_attributes(idl_name, child)
579d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            elif child_class == 'Argument':
580d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                child_name = child.GetName()
581d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if child_name != '...':
582d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    raise ValueError('Unrecognized Argument node; expected "...", got "%s"' % child_name)
583d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                self.is_variadic = child.GetProperty('ELLIPSIS') or False
5845d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            elif child_class == 'Default':
5855d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)                self.default_value = default_node_to_idl_literal(child)
586d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            else:
587d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                raise ValueError('Unrecognized node class: %s' % child_class)
588d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
589d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
590e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)def arguments_node_to_arguments(idl_name, node):
591d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # [Constructor] and [CustomConstructor] without arguments (the bare form)
592d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # have None instead of an arguments node, but have the same meaning as using
593d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # an empty argument list, [Constructor()], so special-case this.
594d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # http://www.w3.org/TR/WebIDL/#Constructor
595d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if node is None:
596d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return []
597e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    return [IdlArgument(idl_name, argument_node)
598d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            for argument_node in node.GetChildren()]
599d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
600d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
601d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
602197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch# Stringifiers
603197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch################################################################################
604197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
605197021e6b966cfb06891637935ef33fff06433d1Ben Murdochclass IdlStringifier(object):
606e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    def __init__(self, idl_name, node):
607197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        self.attribute = None
608197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        self.operation = None
609197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        self.extended_attributes = {}
610e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        self.idl_name = idl_name
611197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
612197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        for child in node.GetChildren():
613197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            child_class = child.GetClass()
614197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            if child_class == 'Attribute':
615e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                self.attribute = IdlAttribute(idl_name, child)
616197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            elif child_class == 'Operation':
617e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                operation = IdlOperation(idl_name, child)
618197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                if operation.name:
619197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                    self.operation = operation
620197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            elif child_class == 'ExtAttributes':
621e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                self.extended_attributes = ext_attributes_node_to_extended_attributes(idl_name, child)
622197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            else:
623197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                raise ValueError('Unrecognized node class: %s' % child_class)
624197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
625197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        # Copy the stringifier's extended attributes (such as [Unforgable]) onto
626197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        # the underlying attribute or operation, if there is one.
627197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if self.attribute or self.operation:
628197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            (self.attribute or self.operation).extended_attributes.update(
629197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                self.extended_attributes)
630197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
631197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
632197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch################################################################################
633d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# Extended attributes
634d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
635d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
636e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)def ext_attributes_node_to_extended_attributes(idl_name, node):
637d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    """
638d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    Returns:
639d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)      Dictionary of {ExtAttributeName: ExtAttributeValue}.
6407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci      Value is usually a string, with these exceptions:
641d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)      Constructors: value is a list of Arguments nodes, corresponding to
642d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        possible signatures of the constructor.
643d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)      CustomConstructors: value is a list of Arguments nodes, corresponding to
644d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        possible signatures of the custom constructor.
645d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)      NamedConstructor: value is a Call node, corresponding to the single
646d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        signature of the named constructor.
6477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci      SetWrapperReferenceTo: value is an Arguments node.
648d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    """
649d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # Primarily just make a dictionary from the children.
650d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # The only complexity is handling various types of constructors:
651d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # Constructors and Custom Constructors can have duplicate entries due to
652d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # overloading, and thus are stored in temporary lists.
653d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # However, Named Constructors cannot be overloaded, and thus do not have
654d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # a list.
655d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # FIXME: move Constructor logic into separate function, instead of modifying
656d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    #        extended attributes in-place.
657d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    constructors = []
658d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    custom_constructors = []
659d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    extended_attributes = {}
660d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
661d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    def child_node(extended_attribute_node):
662d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        children = extended_attribute_node.GetChildren()
663d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if not children:
664d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return None
665d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if len(children) > 1:
666d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            raise ValueError('ExtAttributes node with %s children, expected at most 1' % len(children))
667d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return children[0]
668d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
669d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    extended_attribute_node_list = node.GetChildren()
670d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    for extended_attribute_node in extended_attribute_node_list:
671d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        name = extended_attribute_node.GetName()
672d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        child = child_node(extended_attribute_node)
673d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        child_class = child and child.GetClass()
674d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if name == 'Constructor':
675d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if child_class and child_class != 'Arguments':
676d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                raise ValueError('Constructor only supports Arguments as child, but has child of class: %s' % child_class)
677d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            constructors.append(child)
678d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        elif name == 'CustomConstructor':
679d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if child_class and child_class != 'Arguments':
680d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                raise ValueError('[CustomConstructor] only supports Arguments as child, but has child of class: %s' % child_class)
681d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            custom_constructors.append(child)
682d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        elif name == 'NamedConstructor':
683d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if child_class and child_class != 'Call':
684d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                raise ValueError('[NamedConstructor] only supports Call as child, but has child of class: %s' % child_class)
685d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            extended_attributes[name] = child
686d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        elif name == 'SetWrapperReferenceTo':
687d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if not child:
688d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                raise ValueError('[SetWrapperReferenceTo] requires a child, but has none.')
689d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if child_class != 'Arguments':
690d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                raise ValueError('[SetWrapperReferenceTo] only supports Arguments as child, but has child of class: %s' % child_class)
691e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            extended_attributes[name] = arguments_node_to_arguments(idl_name, child)
692d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        elif child:
693d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            raise ValueError('ExtAttributes node with unexpected children: %s' % name)
694d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        else:
695d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            value = extended_attribute_node.GetProperty('VALUE')
696d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            extended_attributes[name] = value
697d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
698d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # Store constructors and custom constructors in special list attributes,
699d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # which are deleted later. Note plural in key.
700d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if constructors:
701d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        extended_attributes['Constructors'] = constructors
702d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if custom_constructors:
703d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        extended_attributes['CustomConstructors'] = custom_constructors
704d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
705d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return extended_attributes
706d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
707d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
708e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)def extended_attributes_to_constructors(idl_name, extended_attributes):
709d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    """Returns constructors and custom_constructors (lists of IdlOperations).
710d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
711d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    Auxiliary function for IdlInterface.__init__.
712d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    """
713d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
714d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    constructor_list = extended_attributes.get('Constructors', [])
715d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    constructors = [
716e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        IdlOperation.constructor_from_arguments_node('Constructor', idl_name, arguments_node)
717d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for arguments_node in constructor_list]
718d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
719d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    custom_constructor_list = extended_attributes.get('CustomConstructors', [])
720d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    custom_constructors = [
721e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        IdlOperation.constructor_from_arguments_node('CustomConstructor', idl_name, arguments_node)
722d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        for arguments_node in custom_constructor_list]
723d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
724d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if 'NamedConstructor' in extended_attributes:
725d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # FIXME: support overloaded named constructors, and make homogeneous
726d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        name = 'NamedConstructor'
727d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        call_node = extended_attributes['NamedConstructor']
728d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        extended_attributes['NamedConstructor'] = call_node.GetName()
729d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        children = call_node.GetChildren()
730d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if len(children) != 1:
731d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            raise ValueError('NamedConstructor node expects 1 child, got %s.' % len(children))
732d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        arguments_node = children[0]
733e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        named_constructor = IdlOperation.constructor_from_arguments_node('NamedConstructor', idl_name, arguments_node)
734d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # FIXME: should return named_constructor separately; appended for Perl
735d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        constructors.append(named_constructor)
736d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
737d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return constructors, custom_constructors
738d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
739d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
740d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)def clear_constructor_attributes(extended_attributes):
741d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # Deletes Constructor*s* (plural), sets Constructor (singular)
742d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if 'Constructors' in extended_attributes:
743d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        del extended_attributes['Constructors']
744d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        extended_attributes['Constructor'] = None
745d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if 'CustomConstructors' in extended_attributes:
746d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        del extended_attributes['CustomConstructors']
747d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        extended_attributes['CustomConstructor'] = None
748d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
749d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
750d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
751d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)# Types
752d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)################################################################################
753d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
754d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)def type_node_to_type(node):
755d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    children = node.GetChildren()
756d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if len(children) < 1 or len(children) > 2:
757d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        raise ValueError('Type node expects 1 or 2 children (type + optional array []), got %s (multi-dimensional arrays are not supported).' % len(children))
758d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
7599e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    base_type = type_node_inner_to_type(children[0])
7609e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
7619e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    if node.GetProperty('NULLABLE'):
7629e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        base_type = IdlNullableType(base_type)
763d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
764d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if len(children) == 2:
765d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        array_node = children[1]
766d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        array_node_class = array_node.GetClass()
767d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if array_node_class != 'Array':
768d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            raise ValueError('Expected Array node as TypeSuffix, got %s node.' % array_node_class)
7699e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        array_type = IdlArrayType(base_type)
7709e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        if array_node.GetProperty('NULLABLE'):
7719e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            return IdlNullableType(array_type)
7729e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        return array_type
773d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
774e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    return base_type
775d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
776d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
7779e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)def type_node_inner_to_type(node):
778d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    node_class = node.GetClass()
779d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # Note Type*r*ef, not Typedef, meaning the type is an identifier, thus
780d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # either a typedef shorthand (but not a Typedef declaration itself) or an
781d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    # interface type. We do not distinguish these, and just use the type name.
782d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if node_class in ['PrimitiveType', 'Typeref']:
783f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        # unrestricted syntax: unrestricted double | unrestricted float
784f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        is_unrestricted = node.GetProperty('UNRESTRICTED') or False
7859e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        return IdlType(node.GetName(), is_unrestricted=is_unrestricted)
786d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    elif node_class == 'Any':
7879e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        return IdlType('any')
788d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    elif node_class == 'Sequence':
7899e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        return sequence_node_to_type(node)
790d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    elif node_class == 'UnionType':
7919e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        return union_type_node_to_idl_union_type(node)
792d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    raise ValueError('Unrecognized node class: %s' % node_class)
793d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
794d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
7959e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)def sequence_node_to_type(node):
796d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    children = node.GetChildren()
797d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if len(children) != 1:
798d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        raise ValueError('Sequence node expects exactly 1 child, got %s' % len(children))
799d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    sequence_child = children[0]
800d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    sequence_child_class = sequence_child.GetClass()
801d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if sequence_child_class != 'Type':
802d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        raise ValueError('Unrecognized node class: %s' % sequence_child_class)
803e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    element_type = type_node_to_type(sequence_child)
8049e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    sequence_type = IdlSequenceType(element_type)
8059e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    if node.GetProperty('NULLABLE'):
8069e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        return IdlNullableType(sequence_type)
8079e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    return sequence_type
808d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
809d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
810d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)def typedef_node_to_type(node):
811d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    children = node.GetChildren()
812d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if len(children) != 1:
813d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        raise ValueError('Typedef node with %s children, expected 1' % len(children))
814d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    child = children[0]
815d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    child_class = child.GetClass()
816d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if child_class != 'Type':
817d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        raise ValueError('Unrecognized node class: %s' % child_class)
818d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return type_node_to_type(child)
819d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
820d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
8219e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)def union_type_node_to_idl_union_type(node):
822d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    member_types = [type_node_to_type(member_type_node)
823d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    for member_type_node in node.GetChildren()]
8249e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    return IdlUnionType(member_types)
825