| Index: Source/bindings/scripts/ir.py
|
| diff --git a/Source/bindings/scripts/ir.py b/Source/bindings/scripts/ir.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..34eebbd932f2f8e9bd55fa225d75715154c5a4e3
|
| --- /dev/null
|
| +++ b/Source/bindings/scripts/ir.py
|
| @@ -0,0 +1,382 @@
|
| +# 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.
|
| +
|
| +"""Blink IDL Intermediate Representation (IR) classes
|
| +
|
| +Also JSON export (and partial import) methods,
|
| +for use by json_import_export.py.
|
| +"""
|
| +
|
| +import json
|
| +import os.path
|
| +
|
| +# from blink_idl_parser import BlinkIDLParser
|
| +
|
| +
|
| +def none_to_value_is_missing(extended_attributes):
|
| + # Perl IDL Parser uses 'VALUE_IS_MISSING' for null values in
|
| + # extended attributes, so add this as a filter when exporting to JSON.
|
| + new_extended_attributes = {}
|
| + for key, value in extended_attributes.iteritems():
|
| + if value is None:
|
| + new_extended_attributes[key] = 'VALUE_IS_MISSING'
|
| + else:
|
| + new_extended_attributes[key] = value
|
| + return new_extended_attributes
|
| +
|
| +
|
| +def value_is_missing_to_none(extended_attributes):
|
| + # Perl IDL Parser uses 'VALUE_IS_MISSING' for null values in
|
| + # extended attributes, so add this as a filter when importing from JSON.
|
| + new_extended_attributes = {}
|
| + for key, value in extended_attributes.iteritems():
|
| + if value == 'VALUE_IS_MISSING':
|
| + new_extended_attributes[key] = None
|
| + else:
|
| + new_extended_attributes[key] = value
|
| + return new_extended_attributes
|
| +
|
| +
|
| +def boolean_to_perl(value):
|
| + # Perl stores booleans as 1, 0, or undefined (JSON null);
|
| + # convert to this format
|
| + if value is None:
|
| + return None
|
| + return int(value)
|
| +
|
| +
|
| +def perl_to_boolean(value):
|
| + # Perl stores booleans as 1, 0, or undefined (JSON null);
|
| + # convert from this format
|
| + if value is None:
|
| + return None
|
| + return bool(value)
|
| +
|
| +
|
| +class IdlBase():
|
| + pass
|
| +
|
| +
|
| +class IdlDocument(IdlBase):
|
| + def __init__(self, callback_functions=None, enumerations=None, file_name=None, interfaces=None, typedefs=None):
|
| + interfaces = interfaces or []
|
| + if typedefs:
|
| + for interface in interfaces:
|
| + interface.apply_typedefs(typedefs)
|
| +
|
| + self.callback_functions = callback_functions or []
|
| + self.enumerations = enumerations or []
|
| + if file_name:
|
| + self.file_name = os.path.abspath(file_name)
|
| + self.interfaces = interfaces
|
| +
|
| + def to_json(self):
|
| + return {
|
| + 'idlDocument::callbackFunctions': self.callback_functions,
|
| + 'idlDocument::enumerations': self.enumerations,
|
| + 'idlDocument::fileName': self.file_name,
|
| + 'idlDocument::interfaces': self.interfaces,
|
| + }
|
| +
|
| + def from_json(self, json_dict):
|
| + callback_functions = []
|
| + callback_function_list_json = json_dict['callbackFunctions'] or []
|
| + for callback_function_json in callback_function_list_json:
|
| + # FIXME: how are these handled?
|
| + pass
|
| + # callback_function = DomFunction()
|
| + # callback_function.from_json(callback_function_json)
|
| + # callback_functions.append(callback_function)
|
| + self.callback_functions = callback_functions
|
| +
|
| + enumerations = []
|
| + enumeration_list_json = json_dict['enumerations'] or []
|
| + for enumeration_json in enumeration_list_json:
|
| + enumeration = DomEnum()
|
| + enumeration.from_json(enumeration_json)
|
| + enumerations.append(enumeration)
|
| + self.enumerations = enumerations
|
| +
|
| + self.file_name = json_dict['fileName']
|
| +
|
| + interfaces = []
|
| + interface_list_json = json_dict['interfaces'] or []
|
| + for interface_json in interface_list_json:
|
| + interface = DomInterface()
|
| + interface.from_json(interface_json)
|
| + interfaces.append(interface)
|
| + self.interfaces = interfaces
|
| +
|
| +
|
| +class DomInterface(IdlBase):
|
| + def __init__(self, name=None, parents=None, constants=None, functions=None, attributes=None, extended_attributes=None, constructors=None, custom_constructors=None, is_exception=None, is_callback=None, is_partial=None):
|
| + """
|
| + parents: list of strings
|
| + constants: list of DomConstants
|
| + functions: list of DomFunctions
|
| + attributes: list of DomAttributes
|
| + constructors: list of DomFunctions
|
| + custom_constructors: list of DomFunctions
|
| + is_exception: used for exceptions
|
| + """
|
| + self.name = name
|
| + self.parents = parents or []
|
| + self.constants = constants or []
|
| + self.functions = functions or []
|
| + self.attributes = attributes or []
|
| + self.extended_attributes = extended_attributes or {}
|
| + self.constructors = constructors or []
|
| + self.custom_constructors = custom_constructors or []
|
| + self.is_exception = is_exception
|
| + self.is_callback = is_callback
|
| + self.is_partial = is_partial
|
| +
|
| + def apply_typedefs(self, typedefs):
|
| + for constant in self.constants:
|
| + constant.apply_typedefs(typedefs)
|
| + for attribute in self.attributes:
|
| + attribute.apply_typedefs(typedefs)
|
| + for function in self.functions:
|
| + function.apply_typedefs(typedefs)
|
| +
|
| + def to_json(self):
|
| + return {
|
| + 'domInterface::name': self.name,
|
| + 'domInterface::parents': self.parents,
|
| + 'domInterface::constants': self.constants,
|
| + 'domInterface::functions': self.functions,
|
| + 'domInterface::attributes': self.attributes,
|
| + 'domInterface::extendedAttributes': none_to_value_is_missing(self.extended_attributes),
|
| + 'domInterface::constructors': self.constructors,
|
| + 'domInterface::customConstructors': self.custom_constructors,
|
| + 'domInterface::isException': boolean_to_perl(self.is_exception),
|
| + 'domInterface::isCallback': boolean_to_perl(self.is_callback),
|
| + 'domInterface::isPartial': self.is_partial,
|
| + }
|
| +
|
| + def from_json(self, json_dict):
|
| + self.name = json_dict['name']
|
| + self.parents = json_dict['parents'] or []
|
| + self.constants = json_dict['constants'] or []
|
| +
|
| + functions = []
|
| + function_list_json = json_dict['functions'] or []
|
| + for function_json in function_list_json:
|
| + function = DomFunction()
|
| + function.from_json(function_json)
|
| + functions.append(function)
|
| + self.functions = functions
|
| +
|
| + attributes = []
|
| + attribute_list_json = json_dict['attributes'] or []
|
| + for attribute_json in attribute_list_json:
|
| + attribute = DomAttribute()
|
| + attribute.from_json(attribute_json)
|
| + attributes.append(attribute)
|
| + self.attributes = attributes
|
| +
|
| + self.extended_attributes = value_is_missing_to_none(json_dict['extendedAttributes'])
|
| +
|
| + constructors = []
|
| + constructor_list_json = json_dict['constructors'] or []
|
| + for constructor_json in constructor_list_json:
|
| + constructor = DomFunction()
|
| + constructor.from_json(constructor_json)
|
| + constructors.append(constructors)
|
| + self.constructors = constructors
|
| +
|
| + custom_constructors = []
|
| + custom_constructor_list_json = json_dict['customConstructors'] or []
|
| + for custom_constructor_json in custom_constructor_list_json:
|
| + custom_constructor = DomFunction()
|
| + custom_constructor.from_json(custom_constructor_json)
|
| + custom_constructors.append(custom_constructors)
|
| + self.custom_constructors = custom_constructors
|
| +
|
| + self.is_exception = perl_to_boolean(json_dict['isException'])
|
| + self.is_callback = perl_to_boolean(json_dict['isCallback'])
|
| + self.is_partial = json_dict['isPartial']
|
| +
|
| +
|
| +class DomFunction(IdlBase):
|
| + def __init__(self, is_static=None, name=None, data_type=None, extended_attributes=None, specials=None, parameters=None, overloaded_index=None):
|
| + """parameters: List of DomParameters"""
|
| + self.is_static = is_static
|
| + self.name = name or ""
|
| + self.data_type = data_type
|
| + self.extended_attributes = extended_attributes or {}
|
| + self.specials = specials or []
|
| + self.parameters = parameters or []
|
| + self.overloaded_index = overloaded_index
|
| +
|
| + def apply_typedefs(self, typedefs):
|
| + # FIXME: apply!
|
| + print 'Typedef in function!'
|
| +
|
| + def to_json(self):
|
| + return {
|
| + 'domFunction::isStatic': self.is_static,
|
| + 'domFunction::name': self.name,
|
| + 'domFunction::type': self.data_type,
|
| + 'domFunction::extendedAttributes': none_to_value_is_missing(self.extended_attributes),
|
| + 'domFunction::specials': self.specials,
|
| + 'domFunction::parameters': self.parameters,
|
| + 'domFunction::overloadedIndex': self.overloaded_index,
|
| + }
|
| +
|
| + def from_json(self, json_dict):
|
| + # FIXME
|
| + return DomFunction()
|
| +
|
| +
|
| +class DomParameter(IdlBase):
|
| + def __init__(self, name=None, data_type=None, extended_attributes=None, is_optional=False, is_nullable=None, is_variadic=False):
|
| + """Used to represent a map of 'variable name' <-> 'variable type'
|
| +
|
| + data_type: string or UnionType
|
| + is_optional: (optional T)
|
| + is_nullable: (T?)
|
| + is_variadic: (long... numbers)
|
| + """
|
| + # FIXME: boolean values are inconsistent (due to Perl),
|
| + # being sometimes True, False, or None (Perl: 1, 0, undef)
|
| + # Should all default to False, and be either True or False
|
| + self.name = name
|
| + self.data_type = data_type
|
| + self.extended_attributes = extended_attributes or {}
|
| + if is_optional is None:
|
| + is_optional = False
|
| + if is_variadic is None:
|
| + is_variadic = False
|
| + self.is_optional = boolean_to_perl(is_optional)
|
| + self.is_nullable = is_nullable
|
| + self.is_variadic = boolean_to_perl(is_variadic)
|
| +
|
| + def to_json(self):
|
| + return {
|
| + 'domParameter::name': self.name,
|
| + 'domParameter::type': self.data_type,
|
| + 'domParameter::extendedAttributes': none_to_value_is_missing(self.extended_attributes),
|
| + 'domParameter::isOptional': self.is_optional,
|
| + 'domParameter::isNullable': self.is_nullable,
|
| + 'domParameter::isVariadic': self.is_variadic,
|
| + }
|
| +
|
| +
|
| +class DomAttribute(IdlBase):
|
| + def __init__(self, data_type=None, name=None, is_nullable=None, is_static=None, is_read_only=None, getter_exceptions=None, setter_exceptions=None, extended_attributes=None):
|
| + """data_type: Attribute type (including namespace), string or UnionType
|
| + is_nullable: (T?)
|
| + getter_exceptions: Possibly raised exceptions
|
| + setter_exceptions: Possibly raised exceptions
|
| + """
|
| + self.data_type = data_type
|
| + self.name = name
|
| + self.is_nullable = is_nullable
|
| + self.is_static = is_static
|
| + self.is_read_only = is_read_only
|
| + self.getter_exceptions = getter_exceptions or []
|
| + self.setter_exceptions = setter_exceptions or []
|
| + self.extended_attributes = extended_attributes or {}
|
| +
|
| + def apply_typedefs(self, typedefs):
|
| + # FIXME: apply!
|
| + print 'Typedef in attribute!'
|
| +
|
| + def to_json(self):
|
| + return {
|
| + 'domAttribute::extendedAttributes': none_to_value_is_missing(self.extended_attributes),
|
| + 'domAttribute::getterExceptions': self.getter_exceptions,
|
| + 'domAttribute::isNullable': self.is_nullable,
|
| + 'domAttribute::isReadOnly': self.is_read_only,
|
| + 'domAttribute::isStatic': self.is_static,
|
| + 'domAttribute::name': self.name,
|
| + 'domAttribute::setterExceptions': self.setter_exceptions,
|
| + 'domAttribute::type': self.data_type,
|
| + }
|
| +
|
| + def from_json(self, json_dict):
|
| + self.data_type = json_dict['type']
|
| + self.extended_attributes = value_is_missing_to_none(json_dict['extendedAttributes']) or {}
|
| + self.getter_exceptions = json_dict['getterExceptions'] or []
|
| + self.is_nullable = json_dict['isNullable']
|
| + self.is_read_only = json_dict['isReadOnly']
|
| + self.is_static = json_dict['isStatic']
|
| + self.name = json_dict['name']
|
| + self.setter_exceptions = json_dict['setterExceptions'] or []
|
| +
|
| +
|
| +class DomConstant(IdlBase):
|
| + def __init__(self, name=None, data_type=None, value=None, extended_attributes=None):
|
| + self.name = name
|
| + self.data_type = data_type
|
| + self.value = value
|
| + self.extended_attributes = extended_attributes or {}
|
| +
|
| + def apply_typedefs(self, typedefs):
|
| + data_type = self.data_type
|
| + if data_type in typedefs:
|
| + typedef = typedefs[data_type]
|
| + if typedef.extended_attributes:
|
| + # FIXME: why this restriction?
|
| + raise ValueError('Extended attributes cannot be used in a typedef used in a constant, but typedef %s used in constant %s has extended attributes' % (data_type, self.name))
|
| + self.data_type = typedef.data_type
|
| +
|
| + def to_json(self):
|
| + return {
|
| + 'domConstant::name': self.name,
|
| + 'domConstant::type': self.data_type,
|
| + 'domConstant::value': self.value,
|
| + 'domConstant::extendedAttributes': none_to_value_is_missing(self.extended_attributes),
|
| + }
|
| +
|
| +
|
| +class DomEnum(IdlBase):
|
| + def __init__(self, name=None, values=None):
|
| + """name: enumeration identifier
|
| + values: enumeration values, list of unique strings
|
| + """
|
| + self.name = name
|
| + self.values = values or []
|
| +
|
| + def from_json(self, json_dict):
|
| + # FIXME
|
| + return DomEnum()
|
| +
|
| +
|
| +class Typedef():
|
| + # Not exposed in bindings, internal to IDL parsing
|
| + def __init__(self, extended_attributes=None, data_type=None):
|
| + self.extended_attributes = extended_attributes or {}
|
| + self.data_type = data_type
|
| +
|
| +
|
| +class UnionType(IdlBase):
|
| + def __init__(self, union_member_types=None):
|
| + """union_member_types: list of string or UnionType"""
|
| + self.union_member_types = union_member_types or []
|
|
|