Index: Source/bindings/scripts/code_generator_idl_reader.py |
diff --git a/Source/bindings/scripts/code_generator_idl_reader.py b/Source/bindings/scripts/code_generator_idl_reader.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..96b1d58050d43fb1c3b5a55f441227f547855ae3 |
--- /dev/null |
+++ b/Source/bindings/scripts/code_generator_idl_reader.py |
@@ -0,0 +1,163 @@ |
+# 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. |
+ |
+ |
+""" |
+FIXME: This module should be removed. All IDL file reading should be done in the |
+Parser; the Code Generator should not have to do this. |
+""" |
+ |
+import fnmatch |
+import os |
+import posixpath |
+ |
+import idl_reader |
+ |
+reader = idl_reader.IdlReader() |
+idl_filenames = {} |
+ |
+ |
+def find_idl_files(idl_directories): |
+ directories = [os.path.abspath(directory) for directory in idl_directories] |
+ directories.append('.') |
+ for directory in directories: |
+ for dirpath, _, files in os.walk(directory): |
+ for filename in fnmatch.filter(files, '*.idl'): |
+ root, _ = os.path.splitext(filename) |
+ fullpath = os.path.join(dirpath, filename) |
+ idl_filenames[root] = fullpath |
+ |
+ |
+def idl_filename_for_interface(root_name): |
+ try: |
+ return idl_filenames[root_name] |
+ except KeyError: |
+ # FIXME: This error message should be improved. |
+ # This error occurs during symbol resolution: an unidentified type |
+ # is assumed to be an interface type. |
+ raise Exception('Could NOT find IDL file for interface \'%s\'' % root_name) |
+ |
+ |
+def memoize(f): |
+ """Return a memoized version of a single-variable function. |
+ |
+ Useful as a decorator. |
+ """ |
+ cache = {} |
+ |
+ def memoized_function(x): |
+ if x not in cache: |
+ cache[x] = f(x) |
+ return cache[x] |
+ return memoized_function |
+ |
+ |
+@memoize |
+def _get_interface(root_name): |
+ """Return an interface or partial interface, given a root name. |
+ |
+ Memoized so only parses interfaces once. |
+ |
+ Args: |
+ root_name: the IDL filename minus the extension: Foo for Foo.idl. |
+ This is either the interface name or the root name of a |
+ partial interface file. |
+ """ |
+ idl_filename = idl_filename_for_interface(root_name) |
+ definitions = reader.read_idl_definitions(idl_filename) |
+ interfaces = definitions.interfaces |
+ if root_name in interfaces: |
+ return interfaces[root_name] |
+ if len(interfaces) == 1: |
+ interface = interfaces.values()[0] |
+ if interface.is_partial: |
+ return interface |
+ |
+ raise Exception('Could NOT find interface definition for %s in %s' % (root_name, idl_filename)) |
+ |
+ |
+def ancestors(interface): |
+ yield interface |
+ while interface.parent: |
+ interface = _get_interface(interface.parent) |
+ yield interface |
+ |
+ |
+def base_interface(interface): |
+ return list(ancestors(interface))[-1] |
+ |
+ |
+def base_interface_name(interface): |
+ return base_interface(interface).name |
+ |
+ |
+def inherits_interface(interface, interface_name): |
+ ancestor_names = [ancestor_interface.name for ancestor_interface in ancestors(interface)] |
+ return interface_name in ancestor_names |
+ |
+ |
+def interface_inherits_extended_attribute(interface, extended_attribute): |
+ ancestor_extended_attributes = [ancestor_interface.extended_attributes for ancestor_interface in ancestors(interface)] |
+ return any([extended_attribute in extended_attributes for extended_attributes in ancestor_extended_attributes]) |
+ |
+ |
+def is_callback_interface_base(interface_name): |
+ interface = _get_interface(interface_name) |
+ return interface.is_callback |
+ |
+ |
+def implemented_as_from_implemented_by(implemented_by): |
+ interface = _get_interface(implemented_by) |
+ return interface.extended_attributes.get('ImplementedAs', implemented_by) |
+ |
+ |
+def _implemented_as_cpp_name(definition_or_member): |
+ """ |
+ For interfaces, this is the class name. |
+ For interface members (attributes and operations), this is the method name. |
+ For attributes, this is also used in the getter and setter. |
+ """ |
+ # FIXME: duplicated from types |
+ return definition_or_member.extended_attributes.get('ImplementedAs', definition_or_member.name) |
+ |
+ |
+def implemented_as_cpp_name_from_idl_type(idl_type): |
+ interface = _get_interface(idl_type) |
+ return _implemented_as_cpp_name(interface) |
+ |
+ |
+def _get_relative_dir_posix(filename): |
+ """Returns relative directory to a local file, in POSIX format.""" |
+ relative_path_local = os.path.relpath(filename) |
+ relative_dir_local = os.path.dirname(relative_path_local) |
+ return relative_dir_local.replace(os.path.sep, posixpath.sep) |
+ |
+ |
+def idl_file_rel_dir_posix(interface_name): |
+ idl_filename = idl_filename_for_interface(interface_name) |
+ return _get_relative_dir_posix(idl_filename) |