Chromium Code Reviews| Index: Source/bindings/scripts/idl_definitions_builder.py |
| diff --git a/Source/bindings/scripts/idl_definitions_builder.py b/Source/bindings/scripts/idl_definitions_builder.py |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..05bb4738347441e8df7316f476f2c9fe47ac4b4b |
| --- /dev/null |
| +++ b/Source/bindings/scripts/idl_definitions_builder.py |
| @@ -0,0 +1,512 @@ |
| +# Copyright (C) 2013 Google Inc. All rights reserved. |
| +# |
| +# Redistribution and use in source and binary forms, with or without |
| +# modification, are permitted provided that the following conditions are |
| +# met: |
| +# |
| +# * Redistributions of source code must retain the above copyright |
| +# notice, this list of conditions and the following disclaimer. |
| +# * Redistributions in binary form must reproduce the above |
| +# copyright notice, this list of conditions and the following disclaimer |
| +# in the documentation and/or other materials provided with the |
| +# distribution. |
| +# * Neither the name of Google Inc. nor the names of its |
| +# contributors may be used to endorse or promote products derived from |
| +# this software without specific prior written permission. |
| +# |
| +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| + |
| +"""Builds an IdlDefinitions object from an AST (produced by blink_idl_parser).""" |
| + |
| +from idl_definitions import IdlDefinitions, IdlInterface, IdlException, IdlOperation, IdlCallbackFunction, IdlArgument, IdlAttribute, IdlConstant, IdlEnum, IdlTypedef, IdlUnionType |
| + |
| +SPECIAL_KEYWORD_LIST = ['GETTER', 'SETTER', 'DELETER'] |
| + |
| + |
| +def idl_definitions_from_ast(node): |
|
haraken
2013/07/22 01:50:23
Nit: build_idl_definitions_from_ast ?
Nils Barth (inactive)
2013/07/22 06:32:01
Done.
|
| + if node is None: |
| + return None |
| + node_class = node.GetClass() |
| + if node_class != 'File': |
| + raise ValueError('Unrecognized node class: %s' % node_class) |
| + return file_node_to_idl_definitions(node) |
| + |
| + |
| +def file_node_to_idl_definitions(node): |
| + callback_functions = {} |
| + enumerations = {} |
| + exceptions = {} |
| + file_name = node.GetName() # FIXME: only needed for Perl, remove later |
| + interfaces = {} |
| + typedefs = {} |
| + |
| + children = node.GetChildren() |
| + for child in children: |
| + child_class = child.GetClass() |
| + if child_class == 'Interface': |
| + interface = interface_node_to_idl_interface(child) |
| + interfaces[interface.name] = interface |
| + elif child_class == 'Exception': |
| + exception = exception_node_to_idl_exception(child) |
| + exceptions[exception.name] = exception |
| + elif child_class == 'Typedef': |
| + type_name = child.GetName() |
| + typedefs[type_name] = typedef_node_to_idl_typedef(child) |
| + elif child_class == 'Enum': |
| + enumeration = enum_node_to_idl_enum(child) |
| + enumerations[enumeration.name] = enumeration |
| + elif child_class == 'Callback': |
| + callback_function = callback_node_to_idl_callback_function(child) |
| + callback_functions[callback_function.name] = callback_function |
| + elif child_class == 'Implements': |
| + # Implements is handled at the interface merging step |
| + pass |
| + else: |
| + raise ValueError('Unrecognized node class: %s' % child_class) |
| + |
| + return IdlDefinitions(callback_functions=callback_functions, enumerations=enumerations, exceptions=exceptions, file_name=file_name, interfaces=interfaces, typedefs=typedefs) |
| + |
| +# Interface |
|
haraken
2013/07/22 01:50:23
# Definitions for Interface components
Nils Barth (inactive)
2013/07/22 06:32:01
Done. Slight wording change to stay closer to spec
|
| + |
| + |
| +def interface_node_to_idl_interface(node): |
| + attributes = [] |
| + constants = [] |
| + constructors = None |
| + custom_constructors = None |
| + extended_attributes = None |
|
haraken
2013/07/22 01:50:23
Nit: extended_attributes = {}
Nils Barth (inactive)
2013/07/22 06:32:01
That’s handled by IdlDefinitions.__init__ -- I’m u
|
| + functions = [] |
|
haraken
2013/07/22 01:50:23
Probably we should rename 'function' to 'operation
Nils Barth (inactive)
2013/07/22 06:32:01
(>.<) Missed this one. Fixed throughout.
|
| + is_callback = node.GetProperty('CALLBACK') or False |
| + # FIXME: uppercase 'Partial' in base IDL parser |
| + is_partial = node.GetProperty('Partial') or False |
| + name = node.GetName() |
| + parent = None |
| + |
| + children = node.GetChildren() |
| + for child in children: |
| + child_class = child.GetClass() |
| + if child_class == 'Attribute': |
| + attribute = attribute_node_to_idl_attribute(child) |
| + # FIXME: This is a hack to support [CustomConstructor] for |
| + # window.HTMLImageElement. Remove the hack. |
| + clear_constructor_attributes(attribute.extended_attributes) |
| + attributes.append(attribute) |
| + elif child_class == 'Const': |
| + constants.append(constant_node_to_idl_constant(child)) |
| + elif child_class == 'ExtAttributes': |
| + extended_attributes = ext_attributes_node_to_extended_attributes(child) |
| + constructors, custom_constructors = extended_attributes_to_constructors(extended_attributes) |
| + clear_constructor_attributes(extended_attributes) |
| + elif child_class == 'Operation': |
| + functions.append(operation_node_to_idl_operation(child)) |
| + elif child_class == 'Inherit': |
| + parent = child.GetName() |
| + else: |
| + raise ValueError('Unrecognized node class: %s' % child_class) |
| + |
| + return IdlInterface(name=name, attributes=attributes, constants=constants, constructors=constructors, custom_constructors=custom_constructors, extended_attributes=extended_attributes, functions=functions, is_callback=is_callback, is_partial=is_partial, parent=parent) |
| + |
| + |
| +def attribute_node_to_idl_attribute(node): |
| + data_type = None |
| + extended_attributes = {} |
| + is_nullable = False |
| + is_read_only = node.GetProperty('READONLY') or False |
| + is_static = node.GetProperty('STATIC') or False |
| + name = node.GetName() |
| + |
| + children = node.GetChildren() |
| + for child in children: |
| + child_class = child.GetClass() |
| + if child_class == 'Type': |
| + data_type = type_node_to_type(child) |
| + is_nullable = child.GetProperty('NULLABLE') or False |
| + elif child_class == 'ExtAttributes': |
| + extended_attributes = ext_attributes_node_to_extended_attributes(child) |
| + else: |
| + raise ValueError('Unrecognized node class: %s' % child_class) |
| + |
| + return IdlAttribute(data_type=data_type, extended_attributes=extended_attributes, is_nullable=is_nullable, is_read_only=is_read_only, is_static=is_static, name=name) |
| + |
| + |
| +def constant_node_to_idl_constant(node): |
| + name = node.GetName() |
| + |
| + children = node.GetChildren() |
| + num_children = len(children) |
| + if num_children < 2 or num_children > 3: |
| + raise ValueError('Expected 2 or 3 children, got %s' % num_children) |
| + |
| + type_node = children[0] |
| + data_type = type_node_inner_to_type(type_node) |
|
haraken
2013/07/22 01:50:23
Shouldn't this be type_node_to_type ?
Nils Barth (inactive)
2013/07/22 06:32:01
No, “inner” is intentional: ConstType is simpler t
|
| + |
| + value_node = children[1] |
| + value_node_class = value_node.GetClass() |
| + if value_node_class != 'Value': |
| + raise ValueError('Expected Value node, got %s' % value_node_class) |
| + value = value_node.GetName() |
| + |
| + extended_attributes = None |
|
haraken
2013/07/22 01:50:23
Nit: extended_attributes = {}
Nils Barth (inactive)
2013/07/22 06:32:01
(See above.)
|
| + if num_children == 3: |
| + ext_attributes_node = children[2] |
| + extended_attributes = ext_attributes_node_to_extended_attributes(ext_attributes_node) |
| + |
| + return IdlConstant(data_type=data_type, extended_attributes=extended_attributes, name=name, value=value) |
| + |
| + |
| +def operation_node_to_idl_operation(node): |
| + name = node.GetName() |
| + # FIXME: AST should use None internally |
| + if name == '_unnamed_': |
| + name = None |
| + |
| + is_static = node.GetProperty('STATIC') or False |
| + # FIXME: AST should have a specials_node so don't need to hard-code list |
|
haraken
2013/07/22 01:50:23
Sorry about my previous comment. Given that 'const
Nils Barth (inactive)
2013/07/22 06:32:01
n/p; got it, done.
|
| + specials = [] |
| + property_dictionary = node.GetProperties() |
| + for special_keyword in SPECIAL_KEYWORD_LIST: |
| + if special_keyword in property_dictionary: |
| + specials.append(special_keyword.lower()) |
| + |
| + extended_attributes = None |
|
haraken
2013/07/22 01:50:23
extentded_attributes = {}
Nils Barth (inactive)
2013/07/22 06:32:01
(See above.)
|
| + arguments = [] |
| + return_type = None |
| + children = node.GetChildren() |
| + for child in children: |
| + child_class = child.GetClass() |
| + if child_class == 'Arguments': |
| + arguments = arguments_node_to_arguments(child) |
| + elif child_class == 'Type': |
| + return_type = type_node_to_type(child) |
| + elif child_class == 'ExtAttributes': |
| + extended_attributes = ext_attributes_node_to_extended_attributes(child) |
| + else: |
| + raise ValueError('Unrecognized node class: %s' % child_class) |
| + |
| + return IdlOperation(name=name, data_type=return_type, extended_attributes=extended_attributes, is_static=is_static, arguments=arguments, specials=specials) |
| + |
| + |
| +def arguments_node_to_arguments(node): |
|
haraken
2013/07/22 01:50:23
arguments_node_to_idl_arguments ?
Nils Barth (inactive)
2013/07/22 06:32:01
That’s potentially confusing, since it suggests th
|
| + # [Constructor] and [CustomConstructor] without arguments have None |
| + # instead of an arguments node (because not [Constructor()]), so |
| + # special-case this. |
|
haraken
2013/07/22 01:50:23
Just to confirm: [Constructor] and [Constructor()]
Nils Barth (inactive)
2013/07/22 06:32:01
Yup, per spec:
http://www.w3.org/TR/WebIDL/#Constr
|
| + if node is None: |
| + return None |
| + arguments = [] |
| + argument_node_list = node.GetChildren() |
| + for argument_node in argument_node_list: |
| + arguments.append(argument_node_to_idl_argument(argument_node)) |
| + return arguments |
| + |
| + |
| +def argument_node_to_idl_argument(node): |
| + name = node.GetName() |
| + |
| + data_type = None |
| + extended_attributes = {} |
| + # FIXME: Boolean values are inconsistent due to Perl compatibility. |
| + # Make all default to False once Perl removed. |
| + is_nullable = False |
| + is_optional = node.GetProperty('OPTIONAL') |
|
haraken
2013/07/22 01:50:23
Nit: is_optional = node.GetProperty('OPTIONAL') or
Nils Barth (inactive)
2013/07/22 06:32:01
Nonono, these are all hacks for Perl compatibility
|
| + is_variadic = None |
|
haraken
2013/07/22 01:50:23
Nit: is_variadic = False
Nils Barth (inactive)
2013/07/22 06:32:01
Ditto (Perl hack).
|
| + children = node.GetChildren() |
| + for child in children: |
| + child_class = child.GetClass() |
| + if child_class == 'Type': |
| + data_type = type_node_to_type(child) |
| + is_nullable = child.GetProperty('NULLABLE') |
|
haraken
2013/07/22 01:50:23
Nit: is_nullable = child.GetProperty('NULLABLE') o
Nils Barth (inactive)
2013/07/22 06:32:01
Ditto (Perl hack).
|
| + elif child_class == 'ExtAttributes': |
| + extended_attributes = ext_attributes_node_to_extended_attributes(child) |
|
haraken
2013/07/22 01:50:23
'ext_attributes' and 'extended_attributes' are mix
Nils Barth (inactive)
2013/07/22 06:32:01
This is following the spec: the grammar rule is ca
|
| + elif child_class == 'Argument': |
| + child_name = child.GetName() |
| + if child_name != '...': |
| + raise ValueError('Unrecognized Argument node; expected "...", got "%s"' % child_name) |
| + is_variadic = child.GetProperty('ELLIPSIS') or False |
| + else: |
| + raise ValueError('Unrecognized node class: %s' % child_class) |
| + |
| + return IdlArgument(name=name, data_type=data_type, extended_attributes=extended_attributes, is_nullable=is_nullable, is_optional=is_optional, is_variadic=is_variadic) |
| + |
| +# Minor definitions |
|
haraken
2013/07/22 01:50:23
# Definitions of non-Interface components
Nils Barth (inactive)
2013/07/22 06:32:01
Done.
|
| + |
| + |
| +def callback_node_to_idl_callback_function(node): |
| + name = node.GetName() |
| + children = node.GetChildren() |
| + num_children = len(children) |
| + if num_children != 2: |
| + raise ValueError('Expected 2 children, got %s' % num_children) |
| + |
| + type_node = children[0] |
| + data_type = type_node_to_type(type_node) |
| + |
| + arguments_node = children[1] |
| + arguments_node_class = arguments_node.GetClass() |
| + if arguments_node_class != 'Arguments': |
| + raise ValueError('Expected Value node, got %s' % arguments_node_class) |
| + arguments = arguments_node_to_arguments(arguments_node) |
| + |
| + return IdlCallbackFunction(name=name, data_type=data_type, arguments=arguments) |
| + |
| + |
| +def enum_node_to_idl_enum(node): |
| + name = node.GetName() |
| + values = [] |
| + for child in node.GetChildren(): |
| + values.append(child.GetName()) |
| + return IdlEnum(name=name, values=values) |
| + |
| + |
| +def exception_operation_node_to_idl_operation(node): |
|
haraken
2013/07/22 01:50:23
Shall we add a FIXME that says this is just for co
Nils Barth (inactive)
2013/07/22 06:32:01
I’ve added a note and a FIXME.
I don’t know if we
|
| + extended_attributes = {} |
| + name = node.GetName() |
| + children = node.GetChildren() |
| + if len(children) < 1 or len(children) > 2: |
| + raise ValueError('ExceptionOperation node with %s children, expected 1 or 2' % len(children)) |
| + |
| + type_node = children[0] |
| + return_type = type_node_to_type(type_node) |
| + |
| + if len(children) > 1: |
| + ext_attributes_node = children[1] |
| + extended_attributes = ext_attributes_node_to_extended_attributes(ext_attributes_node) |
| + |
| + return IdlOperation(name=name, data_type=return_type, extended_attributes=extended_attributes) |
| + |
| + |
| +def exception_node_to_idl_exception(node): |
| + # Exceptions are similar to Interfaces, but simpler |
| + attributes = [] |
| + constants = [] |
| + extended_attributes = None |
|
haraken
2013/07/22 01:50:23
Nit: extended_attributes = {}
Nils Barth (inactive)
2013/07/22 06:32:01
(See above.)
|
| + functions = [] |
| + name = node.GetName() |
| + |
| + children = node.GetChildren() |
| + for child in children: |
| + child_class = child.GetClass() |
| + if child_class == 'Attribute': |
| + attribute = attribute_node_to_idl_attribute(child) |
| + attributes.append(attribute) |
| + elif child_class == 'Const': |
| + constants.append(constant_node_to_idl_constant(child)) |
| + elif child_class == 'ExtAttributes': |
| + extended_attributes = ext_attributes_node_to_extended_attributes(child) |
| + elif child_class == 'ExceptionOperation': |
| + functions.append(exception_operation_node_to_idl_operation(child)) |
| + else: |
| + raise ValueError('Unrecognized node class: %s' % child_class) |
| + |
| + return IdlException(name=name, attributes=attributes, constants=constants, extended_attributes=extended_attributes, functions=functions) |
| + |
| + |
| +def typedef_node_to_idl_typedef(node): |
| + data_type = None |
| + extended_attributes = None |
|
haraken
2013/07/22 01:50:23
Nit: extended_attributes = {}
Nils Barth (inactive)
2013/07/22 06:32:01
(See above.)
|
| + |
| + children = node.GetChildren() |
| + for child in children: |
| + child_class = child.GetClass() |
| + if child_class == 'Type': |
| + data_type = type_node_to_type(child) |
| + elif child_class == 'ExtAttributes': |
| + extended_attributes = ext_attributes_node_to_extended_attributes(child) |
| + raise ValueError('Extended attributes in a typedef are untested!') |
| + else: |
| + raise ValueError('Unrecognized node class: %s' % child_class) |
| + |
| + return IdlTypedef(data_type=data_type, extended_attributes=extended_attributes) |
| + |
| +# Extended attributes |
| + |
| + |
| +def ext_attributes_node_to_extended_attributes(node): |
| + """ |
| + Returns: |
| + Dictionary of {ExtAttributeName: ExtAttributeValue}. |
| + Value is usually a string, with three exceptions: |
| + Constructors: value is a list of Arguments nodes, corresponding to |
| + possibly signatures of the constructor. |
| + CustomConstructors: value is a list of Arguments nodes, corresponding to |
| + possibly signatures of the custom constructor. |
| + NamedConstructor: value is a Call node, corresponding to the single |
| + signature of the named constructor. |
| + """ |
| + # Primarily just make a dictionary from the children. |
| + # The only complexity is handling various types of constructors: |
| + # Constructors and Custom Constructors can have duplicate entries due to |
| + # overloading, and thus are stored in temporary lists. |
| + # However, Named Constructors cannot be overloaded, and thus do not have |
| + # a list. |
| + # FIXME: Add overloading for Named Constructors and remove custom bindings |
| + # for HTMLImageElement |
| + constructors = [] |
| + custom_constructors = [] |
| + extended_attributes = {} |
| + |
| + attribute_list = node.GetChildren() |
| + for attribute in attribute_list: |
| + name = attribute.GetName() |
| + children = attribute.GetChildren() |
| + if name in ['Constructor', 'CustomConstructor', 'NamedConstructor']: |
| + child = None |
| + child_class = None |
| + if children: |
| + if len(children) > 1: |
| + raise ValueError('ExtAttributes node with %s children, expected at most 1' % len(children)) |
| + child = children[0] |
| + child_class = child.GetClass() |
| + if name == 'Constructor': |
| + if child_class and child_class != 'Arguments': |
| + raise ValueError('Constructor only supports Arguments as child, but has child of class: %s' % child_class) |
| + constructors.append(child) |
| + elif name == 'CustomConstructor': |
| + if child_class and child_class != 'Arguments': |
| + raise ValueError('Custom Constructor only supports Arguments as child, but has child of class: %s' % child_class) |
| + custom_constructors.append(child) |
| + else: # name == 'NamedConstructor' |
| + if child_class and child_class != 'Call': |
| + raise ValueError('Named Constructor only supports Call as child, but has child of class: %s' % child_class) |
| + extended_attributes[name] = child |
| + elif children: |
| + raise ValueError('Non-constructor ExtAttributes node with children: %s' % name) |
| + else: |
| + value = attribute.GetProperty('VALUE') |
| + extended_attributes[name] = value |
| + |
| + # Store constructors and custom constructors in special list attributes, |
| + # which are deleted later. Note plural in key. |
| + if constructors: |
| + extended_attributes['Constructors'] = constructors |
| + if custom_constructors: |
| + extended_attributes['CustomConstructors'] = custom_constructors |
| + |
| + return extended_attributes |
| + |
| + |
| +def extended_attributes_to_constructors(extended_attributes): |
| + """Returns constructors and custom_constructors (lists of IdlOperations). |
| + |
| + Auxiliary function for interface_node_to_idl_interface. |
| + """ |
| + constructors = [] |
| + custom_constructors = [] |
| + if 'Constructors' in extended_attributes: |
| + constructor_list = extended_attributes['Constructors'] |
| + # If not overloaded, have index 0, otherwise index from 1 |
| + overloaded_index = 0 if len(constructor_list) == 1 else 1 |
| + for arguments_node in constructor_list: |
| + name = 'Constructor' |
| + arguments = arguments_node_to_arguments(arguments_node) |
| + constructor = IdlOperation(name=name, extended_attributes=extended_attributes, overloaded_index=overloaded_index, arguments=arguments) |
| + constructors.append(constructor) |
| + overloaded_index += 1 |
| + |
| + # Prefix 'CallWith' and 'RaisesException' with 'Constructor' |
| + # FIXME: Change extended attributes to include prefix explicitly. |
| + if 'CallWith' in extended_attributes: |
| + extended_attributes['ConstructorCallWith'] = extended_attributes['CallWith'] |
| + del extended_attributes['CallWith'] |
| + if 'RaisesException' in extended_attributes: |
| + extended_attributes['ConstructorRaisesException'] = extended_attributes['RaisesException'] |
| + del extended_attributes['RaisesException'] |
| + |
| + if 'CustomConstructors' in extended_attributes: |
| + custom_constructor_list = extended_attributes['CustomConstructors'] |
| + # If not overloaded, have index 0, otherwise index from 1 |
| + overloaded_index = 0 if len(custom_constructor_list) == 1 else 1 |
| + for arguments_node in custom_constructor_list: |
| + name = 'CustomConstructor' |
| + arguments = arguments_node_to_arguments(arguments_node) |
| + custom_constructor = IdlOperation(name=name, extended_attributes=extended_attributes, overloaded_index=overloaded_index, arguments=arguments) |
| + custom_constructors.append(custom_constructor) |
| + overloaded_index += 1 |
| + |
| + if 'NamedConstructor' in extended_attributes: |
| + name = 'NamedConstructor' |
| + call_node = extended_attributes['NamedConstructor'] |
| + extended_attributes['NamedConstructor'] = call_node.GetName() |
| + overloaded_index = None # named constructors are not overloaded |
| + children = call_node.GetChildren() |
| + if len(children) != 1: |
| + raise ValueError('NamedConstructor node expects 1 child, got %s.' % len(children)) |
| + arguments_node = children[0] |
| + arguments = arguments_node_to_arguments(arguments_node) |
| + named_constructor = IdlOperation(name=name, extended_attributes=extended_attributes, overloaded_index=overloaded_index, arguments=arguments) |
| + constructors.append(named_constructor) |
| + |
| + return constructors, custom_constructors |
| + |
| + |
| +def clear_constructor_attributes(extended_attributes): |
| + # Deletes Constructor*s* (plural), sets Constructor (singular) |
| + if 'Constructors' in extended_attributes: |
| + del extended_attributes['Constructors'] |
| + extended_attributes['Constructor'] = None |
| + if 'CustomConstructors' in extended_attributes: |
| + del extended_attributes['CustomConstructors'] |
| + extended_attributes['CustomConstructor'] = None |
| + |
| + |
| +# Types |
| + |
| + |
| +def type_node_to_type(node): |
| + children = node.GetChildren() |
| + if len(children) < 1 or len(children) > 2: |
| + raise ValueError('Type node expects 1 or 2 children (type + optional array []), got %s (multi-dimensional arrays are not supported).' % len(children)) |
| + |
| + type_node_child = children[0] |
| + data_type = type_node_inner_to_type(type_node_child) |
| + |
| + if len(children) == 2: |
| + array_node = children[1] |
| + array_node_class = array_node.GetClass() |
| + if array_node_class != 'Array': |
| + raise ValueError('Expected Array node as TypeSuffix, got %s node.' % array_node_class) |
| + data_type += '[]' |
| + |
| + return data_type |
| + |
| + |
| +def type_node_inner_to_type(node): |
| + node_class = node.GetClass() |
| + if node_class in ['PrimitiveType', 'Typeref']: |
|
haraken
2013/07/22 01:50:23
Help me understand: What is Typeref?
Nils Barth (inactive)
2013/07/22 06:32:01
! Good catch! It’s a typo for Type*d*ef in the bas
|
| + return node.GetName() |
| + elif node_class == 'Any': |
| + return 'any' |
| + elif node_class == 'Sequence': |
| + return sequence_node_to_type(node) |
| + elif node_class == 'UnionType': |
| + return union_type_node_to_idl_union_type(node) |
| + raise ValueError('Unrecognized node class: %s' % node_class) |
| + |
| + |
| +def sequence_node_to_type(node): |
| + children = node.GetChildren() |
| + if len(children) != 1: |
| + raise ValueError('Sequence node expects exactly 1 child, got %s' % len(children)) |
| + sequence_child = children[0] |
| + sequence_child_class = sequence_child.GetClass() |
| + if sequence_child_class != 'Type': |
| + raise ValueError('Unrecognized node class: %s' % sequence_child_class) |
| + sequence_type = type_node_to_type(sequence_child) |
| + return 'sequence<%s>' % sequence_type |
| + |
| + |
| +def union_type_node_to_idl_union_type(node): |
| + union_member_types = [] |
| + for member_type_node in node.GetChildren(): |
| + member_type = type_node_inner_to_type(member_type_node) |
|
haraken
2013/07/22 01:50:23
Shouldn't this be type_node_to_type ?
Nils Barth (inactive)
2013/07/22 06:32:01
Good point. I gave a simple definition for UnionMe
|
| + union_member_types.append(member_type) |
| + return IdlUnionType(union_member_types=union_member_types) |