| 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) | 
|  |