def render_template(self, include_paths, header_template, cpp_template, template_context, component=None): template_context['code_generator'] = self.generator_name # Add includes for any dependencies template_context['header_includes'] = normalize_and_sort_includes( template_context['header_includes'], self.snake_case_generated_files) for include_path in include_paths: if component: dependency = idl_filename_to_component(include_path) assert is_valid_component_dependency(component, dependency) includes.add(include_path) template_context['cpp_includes'] = normalize_and_sort_includes( includes, self.snake_case_generated_files) header_text = render_template(header_template, template_context) cpp_text = render_template(cpp_template, template_context) return header_text, cpp_text
def render_templates(self, include_paths, header_template, cpp_template, context, component=None): context['code_generator'] = self.generator_name # Add includes for any dependencies for include_path in include_paths: if component: dependency = idl_filename_to_component(include_path) assert is_valid_component_dependency(component, dependency) includes.add(include_path) context['header_forward_decls'] = sorted( context.get('header_forward_decls', set())) cpp_includes = set(context.get('cpp_includes', [])) context['cpp_includes'] = normalize_and_sort_includes(cpp_includes | includes) context['header_includes'] = normalize_and_sort_includes( context['header_includes']) header_text = render_template(header_template, context) cpp_text = render_template(cpp_template, context) return header_text, cpp_text
def render_template(include_paths, header_template, cpp_template, template_context, component=None): template_context['code_generator'] = module_pyname # Add includes for any dependencies template_context['header_includes'] = sorted( template_context['header_includes']) for include_path in include_paths: if component: dependency = idl_filename_to_component(include_path) assert is_valid_component_dependency(component, dependency) includes.add(include_path) template_context['cpp_includes'] = sorted(includes) header_text = header_template.render(template_context) cpp_text = cpp_template.render(template_context) return header_text, cpp_text
def render_template(self, include_paths, header_template, cpp_template, template_context, component=None): template_context['code_generator'] = self.generator_name # Add includes for any dependencies template_context['header_includes'] = normalize_and_sort_includes( template_context['header_includes']) for include_path in include_paths: if component: dependency = idl_filename_to_component(include_path) assert is_valid_component_dependency(component, dependency) includes.add(include_path) template_context['cpp_includes'] = normalize_and_sort_includes(includes) header_text = render_template(header_template, template_context) cpp_text = render_template(cpp_template, template_context) return header_text, cpp_text
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 other interfaces that this interface 'implements'. These are merged into the main IdlInterface, as the main IdlInterface implements all these members. Referenced interfaces 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. """ # FIXME: we need to resolve dependency when we implement 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(definitions.interfaces.itervalues()) 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) 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(dependency_definitions.interfaces.itervalues()) dependency_interface_basename, _ = os.path.splitext(os.path.basename(dependency_idl_filename)) transfer_extended_attributes(dependency_interface, dependency_interface_basename) # 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); # RawPtr<...> cppValue(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 implements dependency_interface. # So, # - An interface defined in modules can implement some interface # defined in core. # In this case, we need "NoInterfaceObject" extended attribute. # However, # - An interface defined in core cannot implement any interface # defined in modules. if not is_valid_component_dependency(component, dependency_component): raise Exception('The interface:%s in %s cannot implement ' 'the interface:%s in %s.' % (dependency_interface.name, dependency_component, target_interface.name, component)) if component != dependency_component and 'NoInterfaceObject' not in dependency_interface.extended_attributes: raise Exception('The interface:%s in %s cannot implement ' 'the interface:%s in %s because of ' 'missing NoInterfaceObject.' % (dependency_interface.name, dependency_component, target_interface.name, component)) resolved_definitions[component].update(dependency_definitions) # merges partial interfaces # Implemented interfaces (non-partial dependencies) are also merged # into the target interface, so Code Generator can just iterate # over one list (and not need to handle 'implements' itself). target_interface.merge(dependency_interface) return resolved_definitions
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 other interfaces that this interface 'implements'. These are merged into the main IdlInterface, as the main IdlInterface implements all these members. Referenced interfaces 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. """ # FIXME: we need to resolve dependency when we implement 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(definitions.interfaces.itervalues()) 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(dependency_definitions.interfaces.itervalues()) dependency_interface_basename, _ = os.path.splitext(os.path.basename(dependency_idl_filename)) transfer_extended_attributes(dependency_interface, dependency_interface_basename) # 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* cppValue(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 implements dependency_interface. # So, # - An interface defined in modules can implement some interface # defined in core. # In this case, we need "NoInterfaceObject" extended attribute. # However, # - An interface defined in core cannot implement any interface # defined in modules. if not is_valid_component_dependency(component, dependency_component): raise Exception('The interface:%s in %s cannot implement ' 'the interface:%s in %s.' % (dependency_interface.name, dependency_component, target_interface.name, component)) if component != dependency_component and 'NoInterfaceObject' not in dependency_interface.extended_attributes: raise Exception('The interface:%s in %s cannot implement ' 'the interface:%s in %s because of ' 'missing NoInterfaceObject.' % (dependency_interface.name, dependency_component, target_interface.name, component)) resolved_definitions[component].update(dependency_definitions) # merges partial interfaces # Implemented interfaces (non-partial dependencies) are also merged # into the target interface, so Code Generator can just iterate # over one list (and not need to handle 'implements' itself). target_interface.merge(dependency_interface) 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( dependency_definitions.interfaces.itervalues()) dependency_interface_basename, _ = os.path.splitext( os.path.basename(dependency_idl_filename)) transfer_extended_attributes(dependency_interface, dependency_interface_basename) # 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: 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] dependency_interface.original_interface = target_interface target_interface.partial_interfaces.append(dependency_interface) resolved_definitions[dependency_component] = dependency_definitions else: # Case: target_interface implements dependency_interface. # So, # - An interface defined in modules can implement some interface # defined in core. # In this case, we need "NoInterfaceObject" extended attribute. # However, # - An interface defined in core cannot implement any interface # defined in modules. if not is_valid_component_dependency(component, dependency_component): raise Exception( 'The interface:%s in %s cannot implement ' 'the interface:%s in %s.' % (dependency_interface.name, dependency_component, target_interface.name, component)) if component != dependency_component and 'NoInterfaceObject' not in dependency_interface.extended_attributes: raise Exception( 'The interface:%s in %s cannot implement ' 'the interface:%s in %s because of ' 'missing NoInterfaceObject.' % (dependency_interface.name, dependency_component, target_interface.name, component)) resolved_definitions[component].update( dependency_definitions) # merges partial interfaces # Implemented interfaces (non-partial dependencies) are also merged # into the target interface, so Code Generator can just iterate # over one list (and not need to handle 'implements' itself). target_interface.merge(dependency_interface) 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(dependency_definitions.interfaces.itervalues()) dependency_interface_basename, _ = os.path.splitext(os.path.basename(dependency_idl_filename)) transfer_extended_attributes(dependency_interface, dependency_interface_basename) # 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: 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] dependency_interface.original_interface = target_interface target_interface.partial_interfaces.append(dependency_interface) resolved_definitions[dependency_component] = dependency_definitions else: # Case: target_interface implements dependency_interface. # So, # - An interface defined in modules can implement some interface # defined in core. # In this case, we need "NoInterfaceObject" extended attribute. # However, # - An interface defined in core cannot implement any interface # defined in modules. if not is_valid_component_dependency(component, dependency_component): raise Exception('The interface:%s in %s cannot implement ' 'the interface:%s in %s.' % (dependency_interface.name, dependency_component, target_interface.name, component)) if component != dependency_component and 'NoInterfaceObject' not in dependency_interface.extended_attributes: raise Exception('The interface:%s in %s cannot implement ' 'the interface:%s in %s because of ' 'missing NoInterfaceObject.' % (dependency_interface.name, dependency_component, target_interface.name, component)) resolved_definitions[component].update(dependency_definitions) # merges partial interfaces # Implemented interfaces (non-partial dependencies) are also merged # into the target interface, so Code Generator can just iterate # over one list (and not need to handle 'implements' itself). target_interface.merge(dependency_interface) return resolved_definitions