Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(171)

Unified Diff: Source/bindings/scripts/ir.py

Issue 17572008: WIP IDL compiler rewrite (Closed) Base URL: https://chromium.googlesource.com/chromium/blink@master
Patch Set: non-callback headers working Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/bindings/scripts/implementation.template ('k') | Source/bindings/scripts/run.pl » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 []
« no previous file with comments | « Source/bindings/scripts/implementation.template ('k') | Source/bindings/scripts/run.pl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698