in bindings/scripts/compute_interfaces_info_individual.py [0:0]
def collect_info(self, idl_filename, snake_case_generated_files=False):
"""Reads an idl file and collects information which is required by the
binding code generation."""
def collect_unforgeable_attributes(definition, idl_filename):
"""Collects [Unforgeable] attributes so that we can define them on
sub-interfaces later. The resulting structure is as follows.
interfaces_info[interface_name] = {
'unforgeable_attributes': [IdlAttribute, ...],
...
}
"""
interface_info = {}
unforgeable_attributes = get_unforgeable_attributes_from_definition(definition)
if not unforgeable_attributes:
return interface_info
if definition.is_partial:
interface_basename = idl_filename_to_interface_name(idl_filename)
# TODO(yukishiino): [PartialInterfaceImplementedAs] is treated
# in interface_dependency_resolver.transfer_extended_attributes.
# Come up with a better way to keep them consistent.
for attr in unforgeable_attributes:
attr.extended_attributes['PartialInterfaceImplementedAs'] = definition.extended_attributes.get('ImplementedAs', interface_basename)
interface_info['unforgeable_attributes'] = unforgeable_attributes
return interface_info
definitions = self.reader.read_idl_file(idl_filename)
this_union_types = collect_union_types_from_definitions(definitions)
self.union_types.update(this_union_types)
self.typedefs.update(definitions.typedefs)
for callback_function_name, callback_function in definitions.callback_functions.items():
# Set 'component_dir' to specify a directory that callback function files belong to
self.callback_functions[callback_function_name] = {
'callback_function': callback_function,
'component_dir': idl_filename_to_component(idl_filename),
'full_path': os.path.realpath(idl_filename),
}
# Check enum duplication.
for enum in list(definitions.enumerations.values()):
if not self.check_enum_consistency(enum):
raise Exception('Enumeration "%s" is defined more than once '
'with different valid values' % enum.name)
self.enumerations.update(definitions.enumerations)
if definitions.interfaces:
definition = next(iter(definitions.interfaces.values()))
interface_info = {
'is_callback_interface': definition.is_callback,
'is_dictionary': False,
# Interfaces that are referenced (used as types) and that we
# introspect during code generation (beyond interface-level
# data ([ImplementedAs], is_callback_interface, ancestors, and
# inherited extended attributes): deep dependencies.
# These cause rebuilds of referrers, due to the dependency,
# so these should be minimized; currently only targets of
# [PutForwards].
'referenced_interfaces': get_put_forward_interfaces_from_definition(definition),
}
elif definitions.dictionaries:
definition = next(iter(definitions.dictionaries.values()))
interface_info = {
'is_callback_interface': False,
'is_dictionary': True,
'referenced_interfaces': None,
}
else:
return
if definition.name not in self.interfaces_info:
self.interfaces_info[definition.name] = {}
# Remember [Unforgeable] attributes.
if definitions.interfaces:
merge_dict_recursively(self.interfaces_info[definition.name],
collect_unforgeable_attributes(definition, idl_filename))
component = idl_filename_to_component(idl_filename)
extended_attributes = definition.extended_attributes
implemented_as = extended_attributes.get('ImplementedAs')
full_path = os.path.realpath(idl_filename)
this_include_path = include_path(idl_filename, snake_case_generated_files, implemented_as)
if definition.is_partial:
# We don't create interface_info for partial interfaces, but
# adds paths to another dict.
partial_include_paths = []
if this_include_path:
partial_include_paths.append(this_include_path)
self.add_paths_to_partials_dict(definition.name, full_path, partial_include_paths)
# Collects C++ header paths which should be included from generated
# .cpp files. The resulting structure is as follows.
# interfaces_info[interface_name] = {
# 'cpp_includes': {
# 'core': set(['core/foo/Foo.h', ...]),
# 'modules': set(['modules/bar/Bar.h', ...]),
# },
# ...
# }
if this_include_path:
merge_dict_recursively(
self.interfaces_info[definition.name],
{'cpp_includes': {component: set([this_include_path])}})
return
# '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_definitions(
definitions, definition.name)
interface_info.update({
'extended_attributes': extended_attributes,
'full_path': full_path,
'union_types': this_union_types,
'implemented_as': implemented_as,
'implemented_by_interfaces': left_interfaces,
'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,
'parent': definition.parent,
'relative_dir': relative_dir_posix(idl_filename, source_path),
})
merge_dict_recursively(self.interfaces_info[definition.name], interface_info)