diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/bindings/scripts/interface_dependency_resolver.py')
-rw-r--r-- | chromium/third_party/blink/renderer/bindings/scripts/interface_dependency_resolver.py | 386 |
1 files changed, 0 insertions, 386 deletions
diff --git a/chromium/third_party/blink/renderer/bindings/scripts/interface_dependency_resolver.py b/chromium/third_party/blink/renderer/bindings/scripts/interface_dependency_resolver.py deleted file mode 100644 index 8845480e660..00000000000 --- a/chromium/third_party/blink/renderer/bindings/scripts/interface_dependency_resolver.py +++ /dev/null @@ -1,386 +0,0 @@ -# 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. -"""Resolve interface dependencies, producing a merged IdlDefinitions object. - -This library computes interface dependencies (partial interfaces and -includes), reads the dependency files, and merges them to the IdlDefinitions -for the main IDL file, producing an IdlDefinitions object representing the -entire interface. - -Design doc: http://www.chromium.org/developers/design-documents/idl-compiler#TOC-Dependency-resolution -""" - -import os.path -from utilities import idl_filename_to_component, is_valid_component_dependency, merge_dict_recursively - -# The following extended attributes can be applied to a dependency interface, -# and are then applied to the individual members when merging. -# Note that this moves the extended attribute from the interface to the member, -# which changes the semantics and yields different code than the same extended -# attribute on the main interface. -DEPENDENCY_EXTENDED_ATTRIBUTES = frozenset([ - 'CrossOriginIsolated', - 'DirectSocketEnabled', - 'RuntimeEnabled', - 'SecureContext', -]) - - -class InterfaceDependencyResolver(object): - def __init__(self, interfaces_info, reader): - """Initialize dependency resolver. - - Args: - interfaces_info: - dict of interfaces information, from compute_dependencies.py - reader: - IdlReader, used for reading dependency files - """ - self.interfaces_info = interfaces_info - self.reader = reader - - def resolve_dependencies(self, definitions, component): - """Resolve dependencies, merging them into IDL definitions of main file. - - Dependencies consist of 'partial interface' for the same interface as - in the main file, and mixins that this interface 'includes'. - These are merged into the main IdlInterface, as the main IdlInterface - implements all these members. - - Partial interfaces and mixins are added to IdlDefinitions, but not - merged into the main IdlInterface, as these are only referenced (their - members are introspected, but not implemented in this interface). - - Inherited extended attributes are also added to the main IdlInterface. - - Modifies definitions in place by adding parsed dependencies. - - Args: - definitions: IdlDefinitions object, modified in place - component: - string, describing where the above definitions are defined, - 'core' or 'modules'. See KNOWN_COMPONENTS in utilities.py - - Returns: - A dictionary whose key is component and value is IdlDefinitions - object whose dependency is resolved. - - Raises: - Exception: - A given IdlDefinitions object doesn't have any interfaces, - or a given IdlDefinitions object has incorrect referenced - interfaces. - """ - # TODO(crbug.com/579896): we need to resolve dependency when we - # support partial dictionary. - if not definitions.interfaces: - raise Exception('No need to resolve any dependencies of ' - 'this definition: %s, because this should ' - 'have a dictionary.' % definitions.idl_name) - - target_interface = next(iter(definitions.interfaces.values())) - interface_name = target_interface.name - interface_info = self.interfaces_info[interface_name] - - if 'inherited_extended_attributes' in interface_info: - target_interface.extended_attributes.update( - interface_info['inherited_extended_attributes']) - - resolved_definitions = merge_interface_dependencies( - definitions, component, target_interface, - interface_info['dependencies_full_paths'] + - interface_info['dependencies_other_component_full_paths'], - self.reader) - - inherit_unforgeable_attributes(resolved_definitions, - self.interfaces_info) - - for referenced_interface_name in \ - interface_info['referenced_interfaces']: - referenced_definitions = self.reader.read_idl_definitions( - self.interfaces_info[referenced_interface_name]['full_path']) - - for referenced_component in referenced_definitions: - if not is_valid_component_dependency(component, - referenced_component): - raise Exception('This definitions: %s is defined in %s ' - 'but reference interface:%s is defined ' - 'in %s' % (definitions.idl_name, component, - referenced_interface_name, - referenced_component)) - - resolved_definitions[component].update( - referenced_definitions[component]) - - return resolved_definitions - - -def merge_interface_dependencies(definitions, component, target_interface, - dependency_idl_filenames, reader): - """Merge dependencies ('partial interface' and 'implements') in dependency_idl_filenames into target_interface. - - Args: - definitions: IdlDefinitions object, modified in place - component: - string, describing where the above definitions are defined, - 'core' or 'modules'. See KNOWN_COMPONENTS in utilities.py - target_interface: IdlInterface object, modified in place - dependency_idl_filenames: - Idl filenames which depend on the above definitions. - reader: IdlReader object. - Returns: - A dictionary whose key is component and value is IdlDefinitions - object whose dependency is resolved. - """ - resolved_definitions = {component: definitions} - # Sort so order consistent, so can compare output from run to run. - for dependency_idl_filename in sorted(dependency_idl_filenames): - dependency_definitions = reader.read_idl_file(dependency_idl_filename) - dependency_component = idl_filename_to_component( - dependency_idl_filename) - - dependency_interface = next( - iter(dependency_definitions.interfaces.values())) - - transfer_extended_attributes(dependency_interface, - dependency_idl_filename) - - # We need to use different checkdeps here for partial interface and - # inheritance. - if dependency_interface.is_partial: - # Case: dependency_interface is a partial interface of - # target_interface. - # So, - # - A partial interface defined in modules can update - # the original interface defined in core. - # However, - # - A partial interface defined in core cannot update - # the original interface defined in modules. - if not is_valid_component_dependency(dependency_component, - component): - raise Exception( - 'The partial interface:%s in %s cannot update ' - 'the original interface:%s in %s' % - (dependency_interface.name, dependency_component, - target_interface.name, component)) - - if dependency_component in resolved_definitions: - # When merging a new partial interfaces, should not overwrite - # ImpelemntedAs extended attributes in merged partial - # interface. - # See also the below "if 'ImplementedAs' not in ... " line's - # comment. - dependency_interface.extended_attributes.pop( - 'ImplementedAs', None) - resolved_definitions[dependency_component].update( - dependency_definitions) - continue - - dependency_interface.extended_attributes.update( - target_interface.extended_attributes) - assert target_interface == \ - definitions.interfaces[dependency_interface.name] - # A partial interface should use its original interface's - # ImplementedAs. If the original interface doesn't have, - # remove ImplementedAs defined in the partial interface. - # Because partial interface needs the original interface's - # cpp class to obtain partial interface's cpp class. - # e.g.. V8WindowPartial.cpp: - # DOMWindow* impl = V8Window::ToImpl(holder); - # DOMWindowQuota* cpp_value(DOMWindowQuota::webkitStorageInfo(impl)); - # TODO(tasak): remove ImplementedAs extended attributes - # from all partial interfaces. Instead, rename all cpp/header - # files correctly. ImplementedAs should not be allowed in - # partial interfaces. - if 'ImplementedAs' not in target_interface.extended_attributes: - dependency_interface.extended_attributes.pop( - 'ImplementedAs', None) - dependency_interface.original_interface = target_interface - target_interface.partial_interfaces.append(dependency_interface) - resolved_definitions[dependency_component] = dependency_definitions - else: - # Case: |target_interface| includes |dependency_interface| mixin. - # So, - # - An interface defined in modules can include any interface mixin - # defined in core. - # However, - # - An interface defined in core cannot include an interface mixin - # defined in modules. - if not dependency_interface.is_mixin: - raise Exception( - 'The interface:%s cannot include ' - 'the non-mixin interface: %s.' % - (target_interface.name, dependency_interface.name)) - - if not is_valid_component_dependency(component, - dependency_component): - raise Exception( - 'The interface:%s in %s cannot include ' - 'the interface mixin:%s in %s.' % - (target_interface.name, component, - dependency_interface.name, dependency_component)) - - # merges partial interfaces - resolved_definitions[component].update(dependency_definitions) - # Mixins are also merged into the target interface, so Code - # Generator can just iterate over one list (and not need to handle - # 'includes' itself). - target_interface.merge(dependency_interface) - - return resolved_definitions - - -def transfer_extended_attributes(dependency_interface, - dependency_idl_filename): - """Transfer extended attributes from dependency interface onto members. - - Merging consists of storing certain interface-level data in extended - attributes of the *members* (because there is no separate dependency - interface post-merging). - - The data storing consists of: - * moving certain extended attributes from the dependency interface - to its members (deleting the extended attribute from the interface) - * storing the C++ class of the implementation in an internal - extended attribute of each member, [PartialInterfaceImplementedAs] - - No return: modifies dependency_interface in place. - """ - merged_extended_attributes = {} - for key in DEPENDENCY_EXTENDED_ATTRIBUTES: - if key not in dependency_interface.extended_attributes: - continue - - merged_extended_attributes[key] = \ - dependency_interface.extended_attributes[key] - # Remove the merged attributes from the original dependency interface. - # This ensures that if other dependency interfaces are merged onto this - # one, its extended_attributes do not leak through - # (https://crbug.com/603782). - del dependency_interface.extended_attributes[key] - - # A partial interface's members are implemented as static member functions - # in a separate C++ class. This class name is stored in - # [PartialInterfaceImplementedAs] which is copied from [ImplementedAs] on - # the partial interface definition. - # - # Note that implemented interfaces do *not* need [ImplementedAs], since - # they are implemented on the C++ object |impl| itself, just like members of - # the main interface definition, so the bindings do not need to know in - # which class implemented interfaces are implemented. - # - # Currently [LegacyTreatAsPartialInterface] can be used to have partial - # interface behavior on mixins, but this is being removed as legacy cruft: - # http://crbug.com/360435 - # - # Note that [ImplementedAs] is used with different meanings on interfaces - # and members: - # for Blink class name and function name (or constant name), respectively. - # Thus we do not want to copy this from the interface to the member, but - # instead extract it and handle it separately. - if dependency_interface.is_partial: - if 'ImplementedAs' not in dependency_interface.extended_attributes: - raise ValueError('Partial interface in %s must have ImplementedAs.' - % dependency_idl_filename) - merged_extended_attributes['PartialInterfaceImplementedAs'] = \ - dependency_interface.extended_attributes.pop('ImplementedAs') - elif 'LegacyTreatAsPartialInterface' in \ - dependency_interface.extended_attributes: - merged_extended_attributes['PartialInterfaceImplementedAs'] = ( - dependency_interface.extended_attributes.pop( - 'ImplementedAs', dependency_interface.name)) - - def update_attributes(attributes, extras): - for key, value in extras.items(): - if key not in attributes: - attributes[key] = value - - for attribute in dependency_interface.attributes: - update_attributes(attribute.extended_attributes, - merged_extended_attributes) - for constant in dependency_interface.constants: - update_attributes(constant.extended_attributes, - merged_extended_attributes) - for operation in dependency_interface.operations: - update_attributes(operation.extended_attributes, - merged_extended_attributes) - - -def inherit_unforgeable_attributes(resolved_definitions, interfaces_info): - """Inherits [LegacyUnforgeable] attributes and updates the arguments - accordingly. - - For each interface in |resolved_definitions|, collects all - [LegacyUnforgeable] attributes in ancestor interfaces and adds them to the - interface. 'referenced_interfaces' and 'cpp_includes' in |interfaces_info| - are updated accordingly. - """ - - def collect_unforgeable_attributes_in_ancestors(interface_name, component): - if not interface_name: - # unforgeable_attributes, referenced_interfaces, cpp_includes - return [], [], set() - interface = interfaces_info[interface_name] - unforgeable_attributes, referenced_interfaces, cpp_includes = \ - collect_unforgeable_attributes_in_ancestors( - interface.get('parent'), component) - this_unforgeable = interface.get('unforgeable_attributes', []) - for attr in this_unforgeable: - if attr.defined_in is None: - attr.defined_in = interface_name - unforgeable_attributes.extend(this_unforgeable) - this_referenced = [ - attr.idl_type.base_type for attr in this_unforgeable - if attr.idl_type.base_type in interface.get( - 'referenced_interfaces', []) - ] - referenced_interfaces.extend(this_referenced) - cpp_includes.update( - interface.get('cpp_includes', {}).get(component, {})) - return unforgeable_attributes, referenced_interfaces, cpp_includes - - for component, definitions in resolved_definitions.items(): - for interface_name, interface in definitions.interfaces.items(): - interface_info = interfaces_info[interface_name] - inherited_unforgeable_attributes, referenced_interfaces, cpp_includes = \ - collect_unforgeable_attributes_in_ancestors( - interface_info.get('parent'), component) - # This loop may process the same interface many times, so it's - # possible that we're adding the same attributes twice or more. - # So check if there is a duplicate. - for attr in inherited_unforgeable_attributes: - if attr not in interface.attributes: - interface.attributes.append(attr) - referenced_interfaces.extend( - interface_info.get('referenced_interfaces', [])) - interface_info['referenced_interfaces'] = sorted( - set(referenced_interfaces)) - merge_dict_recursively(interface_info, - {'cpp_includes': { - component: cpp_includes - }}) |