import posixpath
import sys
-from utilities import get_file_contents, write_pickle_file, get_interface_extended_attributes_from_idl, is_callback_interface_from_idl, get_partial_interface_name_from_idl, get_implemented_interfaces_from_idl, get_parent_interface, get_put_forward_interfaces_from_idl
+from utilities import get_file_contents, write_pickle_file, get_interface_extended_attributes_from_idl, is_callback_interface_from_idl, get_partial_interface_name_from_idl, get_implements_from_idl, get_parent_interface, get_put_forward_interfaces_from_idl
module_path = os.path.dirname(__file__)
source_path = os.path.normpath(os.path.join(module_path, os.pardir, os.pardir))
INHERITED_EXTENDED_ATTRIBUTES = set([
'ActiveDOMObject',
'DependentLifetime',
+ 'GarbageCollected',
'WillBeGarbageCollected',
])
extended_attributes = get_interface_extended_attributes_from_idl(idl_file_contents)
implemented_as = extended_attributes.get('ImplementedAs')
- this_include_path = (include_path(idl_filename, implemented_as)
- if 'ImplementedInBaseClass' not in extended_attributes
- else None)
+ this_include_path = include_path(idl_filename, implemented_as)
# Handle partial interfaces
partial_interface_name = get_partial_interface_name_from_idl(idl_file_contents)
# If not a partial interface, the basename is the interface name
interface_name, _ = os.path.splitext(os.path.basename(idl_filename))
+ # 'implements' statements can be included in either the file for the
+ # implement*ing* interface (lhs of 'implements') or implement*ed* interface
+ # (rhs of 'implements'). Store both for now, then merge to implement*ing*
+ # interface later.
+ left_interfaces, right_interfaces = get_implements_from_idl(idl_file_contents, interface_name)
+
interfaces_info[interface_name] = {
'full_path': full_path,
'implemented_as': implemented_as,
- 'implements_interfaces': get_implemented_interfaces_from_idl(idl_file_contents, interface_name),
+ 'implemented_by_interfaces': left_interfaces, # private, merged to next
+ 'implements_interfaces': right_interfaces,
'include_path': this_include_path,
+ # FIXME: temporary private field, while removing old treatement of
+ # 'implements': http://crbug.com/360435
+ 'is_legacy_treat_as_partial_interface': 'LegacyTreatAsPartialInterface' in extended_attributes,
'is_callback_interface': is_callback_interface_from_idl(idl_file_contents),
# Interfaces that are referenced (used as types) and that we introspect
# during code generation (beyond interface-level data ([ImplementedAs],
compute_inheritance_info(interface_name)
# Compute dependencies
+ # Move implements info from implement*ed* interface (rhs of 'implements')
+ # to implement*ing* interface (lhs of 'implements').
+ # Note that moving an 'implements' statement between implementing and
+ # implemented files does not change the info (or hence cause a rebuild)!
+ for right_interface_name, interface_info in interfaces_info.iteritems():
+ for left_interface_name in interface_info['implemented_by_interfaces']:
+ interfaces_info[left_interface_name]['implements_interfaces'].append(right_interface_name)
+ del interface_info['implemented_by_interfaces']
+
# An IDL file's dependencies are partial interface files that extend it,
# and files for other interfaces that this interfaces implements.
for interface_name, interface_info in interfaces_info.iteritems():
partial_interface_paths = partial_interface_files[interface_name]
partial_interfaces_full_paths = partial_interface_paths['full_paths']
+ # Partial interface definitions each need an include, as they are
+ # implemented in separate classes from the main interface.
partial_interfaces_include_paths = partial_interface_paths['include_paths']
implemented_interfaces = interface_info['implements_interfaces']
implemented_interfaces_full_paths = [
implemented_interface_info['full_path']
for implemented_interface_info in implemented_interfaces_info]
+ # Implemented interfaces don't need includes, as this is handled in
+ # the Blink implementation (they are implemented on |impl| itself,
+ # hence header is included in implementing class).
+ # However, they are needed for legacy implemented interfaces that
+ # are being treated as partial interfaces, until we remove these.
+ # http://crbug.com/360435
implemented_interfaces_include_paths = [
implemented_interface_info['include_path']
for implemented_interface_info in implemented_interfaces_info
- if implemented_interface_info['include_path']]
+ if implemented_interface_info['is_legacy_treat_as_partial_interface']]
interface_info.update({
'dependencies_full_paths': (partial_interfaces_full_paths +
implemented_interfaces_include_paths),
})
+ # Clean up temporary private information
+ for interface_info in interfaces_info.itervalues():
+ del interface_info['is_legacy_treat_as_partial_interface']
+
################################################################################