| OLD | NEW |
| 1 # Copyright (C) 2013 Google Inc. All rights reserved. | 1 # Copyright (C) 2013 Google Inc. All rights reserved. |
| 2 # | 2 # |
| 3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
| 4 # modification, are permitted provided that the following conditions are | 4 # modification, are permitted provided that the following conditions are |
| 5 # met: | 5 # met: |
| 6 # | 6 # |
| 7 # * Redistributions of source code must retain the above copyright | 7 # * Redistributions of source code must retain the above copyright |
| 8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
| 9 # * Redistributions in binary form must reproduce the above | 9 # * Redistributions in binary form must reproduce the above |
| 10 # copyright notice, this list of conditions and the following disclaimer | 10 # copyright notice, this list of conditions and the following disclaimer |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 | 30 |
| 31 This library computes interface dependencies (partial interfaces and | 31 This library computes interface dependencies (partial interfaces and |
| 32 implements), reads the dependency files, and merges them to the IdlDefinitions | 32 implements), reads the dependency files, and merges them to the IdlDefinitions |
| 33 for the main IDL file, producing an IdlDefinitions object representing the | 33 for the main IDL file, producing an IdlDefinitions object representing the |
| 34 entire interface. | 34 entire interface. |
| 35 | 35 |
| 36 Design doc: http://www.chromium.org/developers/design-documents/idl-compiler#TOC
-Dependency-resolution | 36 Design doc: http://www.chromium.org/developers/design-documents/idl-compiler#TOC
-Dependency-resolution |
| 37 """ | 37 """ |
| 38 | 38 |
| 39 import os.path | 39 import os.path |
| 40 from utilities import idl_filename_to_component, is_valid_component_dependency | 40 from utilities import idl_filename_to_component, is_valid_component_dependency,
merge_dict_recursively |
| 41 | 41 |
| 42 # The following extended attributes can be applied to a dependency interface, | 42 # The following extended attributes can be applied to a dependency interface, |
| 43 # and are then applied to the individual members when merging. | 43 # and are then applied to the individual members when merging. |
| 44 # Note that this moves the extended attribute from the interface to the member, | 44 # Note that this moves the extended attribute from the interface to the member, |
| 45 # which changes the semantics and yields different code than the same extended | 45 # which changes the semantics and yields different code than the same extended |
| 46 # attribute on the main interface. | 46 # attribute on the main interface. |
| 47 DEPENDENCY_EXTENDED_ATTRIBUTES = frozenset([ | 47 DEPENDENCY_EXTENDED_ATTRIBUTES = frozenset([ |
| 48 'Conditional', | |
| 49 'RuntimeEnabled', | 48 'RuntimeEnabled', |
| 50 'TypeChecking', | |
| 51 ]) | 49 ]) |
| 52 | 50 |
| 53 | 51 |
| 54 class InterfaceDependencyResolver(object): | 52 class InterfaceDependencyResolver(object): |
| 55 def __init__(self, interfaces_info, reader): | 53 def __init__(self, interfaces_info, reader): |
| 56 """Initialize dependency resolver. | 54 """Initialize dependency resolver. |
| 57 | 55 |
| 58 Args: | 56 Args: |
| 59 interfaces_info: | 57 interfaces_info: |
| 60 dict of interfaces information, from compute_dependencies.py | 58 dict of interfaces information, from compute_dependencies.py |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 interface_info['inherited_extended_attributes']) | 110 interface_info['inherited_extended_attributes']) |
| 113 | 111 |
| 114 resolved_definitions = merge_interface_dependencies( | 112 resolved_definitions = merge_interface_dependencies( |
| 115 definitions, | 113 definitions, |
| 116 component, | 114 component, |
| 117 target_interface, | 115 target_interface, |
| 118 interface_info['dependencies_full_paths'] + | 116 interface_info['dependencies_full_paths'] + |
| 119 interface_info['dependencies_other_component_full_paths'], | 117 interface_info['dependencies_other_component_full_paths'], |
| 120 self.reader) | 118 self.reader) |
| 121 | 119 |
| 120 inherit_unforgeable_attributes(resolved_definitions, self.interfaces_inf
o) |
| 121 |
| 122 for referenced_interface_name in interface_info['referenced_interfaces']
: | 122 for referenced_interface_name in interface_info['referenced_interfaces']
: |
| 123 referenced_definitions = self.reader.read_idl_definitions( | 123 referenced_definitions = self.reader.read_idl_definitions( |
| 124 self.interfaces_info[referenced_interface_name]['full_path']) | 124 self.interfaces_info[referenced_interface_name]['full_path']) |
| 125 | 125 |
| 126 for referenced_component in referenced_definitions: | 126 for referenced_component in referenced_definitions: |
| 127 if not is_valid_component_dependency(component, referenced_compo
nent): | 127 if not is_valid_component_dependency(component, referenced_compo
nent): |
| 128 raise Exception('This definitions: %s is defined in %s ' | 128 raise Exception('This definitions: %s is defined in %s ' |
| 129 'but reference interface:%s is defined ' | 129 'but reference interface:%s is defined ' |
| 130 'in %s' % (definitions.idl_name, | 130 'in %s' % (definitions.idl_name, |
| 131 component, | 131 component, |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 for key, value in extras.items(): | 298 for key, value in extras.items(): |
| 299 if key not in attributes: | 299 if key not in attributes: |
| 300 attributes[key] = value | 300 attributes[key] = value |
| 301 | 301 |
| 302 for attribute in dependency_interface.attributes: | 302 for attribute in dependency_interface.attributes: |
| 303 update_attributes(attribute.extended_attributes, merged_extended_attribu
tes) | 303 update_attributes(attribute.extended_attributes, merged_extended_attribu
tes) |
| 304 for constant in dependency_interface.constants: | 304 for constant in dependency_interface.constants: |
| 305 update_attributes(constant.extended_attributes, merged_extended_attribut
es) | 305 update_attributes(constant.extended_attributes, merged_extended_attribut
es) |
| 306 for operation in dependency_interface.operations: | 306 for operation in dependency_interface.operations: |
| 307 update_attributes(operation.extended_attributes, merged_extended_attribu
tes) | 307 update_attributes(operation.extended_attributes, merged_extended_attribu
tes) |
| 308 |
| 309 |
| 310 def inherit_unforgeable_attributes(resolved_definitions, interfaces_info): |
| 311 """Inherits [Unforgeable] attributes and updates the arguments accordingly. |
| 312 |
| 313 For each interface in |resolved_definitions|, collects all [Unforgeable] |
| 314 attributes in ancestor interfaces in the same component and adds them to |
| 315 the interface. 'referenced_interfaces' and 'cpp_includes' in |
| 316 |interfaces_info| are updated accordingly. |
| 317 """ |
| 318 def collect_unforgeable_attributes_in_ancestors(interface_name, component): |
| 319 if not interface_name: |
| 320 # unforgeable_attributes, referenced_interfaces, cpp_includes |
| 321 return [], [], set() |
| 322 interface = interfaces_info[interface_name] |
| 323 unforgeable_attributes, referenced_interfaces, cpp_includes = collect_un
forgeable_attributes_in_ancestors(interface.get('parent'), component) |
| 324 this_unforgeable = interface.get('unforgeable_attributes', {}).get(compo
nent, []) |
| 325 unforgeable_attributes.extend(this_unforgeable) |
| 326 this_referenced = [attr.idl_type.base_type for attr in this_unforgeable |
| 327 if attr.idl_type.base_type in |
| 328 interface.get('referenced_interfaces', [])] |
| 329 referenced_interfaces.extend(this_referenced) |
| 330 cpp_includes.update(interface.get('cpp_includes', {}).get(component, {})
) |
| 331 return unforgeable_attributes, referenced_interfaces, cpp_includes |
| 332 |
| 333 for component, definitions in resolved_definitions.iteritems(): |
| 334 for interface_name, interface in definitions.interfaces.iteritems(): |
| 335 interface_info = interfaces_info[interface_name] |
| 336 inherited_unforgeable_attributes, referenced_interfaces, cpp_include
s = collect_unforgeable_attributes_in_ancestors(interface_info.get('parent'), co
mponent) |
| 337 # This loop may process the same interface many times, so it's |
| 338 # possible that we're adding the same attributes twice or more. |
| 339 # So check if there is a duplicate. |
| 340 for attr in inherited_unforgeable_attributes: |
| 341 if attr not in interface.attributes: |
| 342 interface.attributes.append(attr) |
| 343 referenced_interfaces.extend(interface_info.get('referenced_interfac
es', [])) |
| 344 interface_info['referenced_interfaces'] = sorted(set(referenced_inte
rfaces)) |
| 345 merge_dict_recursively(interface_info, |
| 346 {'cpp_includes': {component: cpp_includes}}) |
| OLD | NEW |