| Index: Source/bindings/scripts/preprocess_idls.py
|
| diff --git a/Source/bindings/scripts/preprocess_idls.py b/Source/bindings/scripts/preprocess_idls.py
|
| deleted file mode 100644
|
| index 46df4fe4805fc60788d264a618f9879843a8c13e..0000000000000000000000000000000000000000
|
| --- a/Source/bindings/scripts/preprocess_idls.py
|
| +++ /dev/null
|
| @@ -1,322 +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.
|
| -
|
| -import optparse
|
| -import os
|
| -import os.path
|
| -import re
|
| -import string
|
| -
|
| -
|
| -def parse_options():
|
| - parser = optparse.OptionParser()
|
| - parser.add_option('--event-names-file', help='output file')
|
| - parser.add_option('--idl-files-list', help='file listing all IDLs')
|
| - parser.add_option('--supplemental-dependency-file', help='output file')
|
| - parser.add_option('--window-constructors-file', help='output file')
|
| - parser.add_option('--workerglobalscope-constructors-file', help='output file')
|
| - parser.add_option('--sharedworkerglobalscope-constructors-file', help='output file')
|
| - parser.add_option('--dedicatedworkerglobalscope-constructors-file', help='output file')
|
| - parser.add_option('--write-file-only-if-changed', type='int', help='if true, do not write an output file if it would be identical to the existing one, which avoids unnecessary rebuilds in ninja')
|
| - options, args = parser.parse_args()
|
| - if options.event_names_file is None:
|
| - parser.error('Must specify an output file using --event-names-file.')
|
| - if options.supplemental_dependency_file is None:
|
| - parser.error('Must specify an output file using --supplemental-dependency-file.')
|
| - if options.window_constructors_file is None:
|
| - parser.error('Must specify an output file using --window-constructors-file.')
|
| - if options.workerglobalscope_constructors_file is None:
|
| - parser.error('Must specify an output file using --workerglobalscope-constructors-file.')
|
| - if options.workerglobalscope_constructors_file is None:
|
| - parser.error('Must specify an output file using --sharedworkerglobalscope-constructors-file.')
|
| - if options.workerglobalscope_constructors_file is None:
|
| - parser.error('Must specify an output file using --dedicatedworkerglobalscope-constructors-file.')
|
| - if options.idl_files_list is None:
|
| - parser.error('Must specify the file listing all IDLs using --idl-files-list.')
|
| - if options.write_file_only_if_changed is None:
|
| - parser.error('Must specify whether file is only written if changed using --write-file-only-if-changed.')
|
| - options.write_file_only_if_changed = bool(options.write_file_only_if_changed)
|
| - if args:
|
| - parser.error('No arguments taken, but "%s" given.' % ' '.join(args))
|
| - return options
|
| -
|
| -
|
| -def get_file_contents(idl_filename):
|
| - with open(idl_filename) as idl_file:
|
| - lines = idl_file.readlines()
|
| - return ''.join(lines)
|
| -
|
| -
|
| -def write_file(new_lines, destination_filename, only_if_changed):
|
| - if only_if_changed and os.path.isfile(destination_filename):
|
| - with open(destination_filename) as destination_file:
|
| - old_lines = destination_file.readlines()
|
| - if old_lines == new_lines:
|
| - return
|
| - with open(destination_filename, 'w') as destination_file:
|
| - destination_file.write(''.join(new_lines))
|
| -
|
| -
|
| -def get_partial_interface_name_from_idl(file_contents):
|
| - match = re.search(r'partial\s+interface\s+(\w+)', file_contents)
|
| - if match:
|
| - return match.group(1)
|
| - return None
|
| -
|
| -
|
| -# identifier-A implements identifier-B;
|
| -# http://www.w3.org/TR/WebIDL/#idl-implements-statements
|
| -def get_implemented_interfaces_from_idl(file_contents, interface_name):
|
| - implemented_interfaces = []
|
| - for match in re.finditer(r'^\s*(\w+)\s+implements\s+(\w+)\s*;', file_contents, re.MULTILINE):
|
| - # identifier-A must be the current interface
|
| - assert match.group(1) == interface_name, \
|
| -"Identifier on the left of the 'implements' statement should be %s in %s.idl, but found %s" % (interface_name, interface_name, match.group(1))
|
| - implemented_interfaces.append(match.group(2))
|
| - return implemented_interfaces
|
| -
|
| -def is_callback_interface_from_idl(file_contents):
|
| - match = re.search(r'callback\s+interface\s+\w+', file_contents)
|
| - return match is not None
|
| -
|
| -
|
| -def get_parent_interface(file_contents):
|
| - match = re.search(r'interface\s+\w+\s*:\s*(\w+)\s*', file_contents)
|
| - if match:
|
| - return match.group(1)
|
| - return None
|
| -
|
| -def get_interface_extended_attributes_from_idl(file_contents):
|
| - extended_attributes = {}
|
| - match = re.search(r'\[(.*)\]\s+(interface|exception)\s+(\w+)',
|
| - file_contents, flags=re.DOTALL)
|
| - if match:
|
| - parts = string.split(match.group(1), ',')
|
| - for part in parts:
|
| - # Match 'key = value'
|
| - match = re.match(r'([^=\s]*)(?:\s*=\s*(.*))?', part.strip())
|
| - key = match.group(1)
|
| - value = match.group(2) or 'VALUE_IS_MISSING'
|
| - if not key:
|
| - continue
|
| - extended_attributes[key] = value
|
| - return extended_attributes
|
| -
|
| -
|
| -def generate_constructor_attribute_list(interface_name, extended_attributes):
|
| - extended_attributes_list = []
|
| - for attribute_name, attribute_value in extended_attributes.iteritems():
|
| - if attribute_name not in ['Conditional', 'EnabledAtRuntime', 'EnabledPerContext']:
|
| - continue
|
| - extended_attribute = attribute_name
|
| - if attribute_value != 'VALUE_IS_MISSING':
|
| - extended_attribute += '=' + attribute_value
|
| - extended_attributes_list.append(extended_attribute)
|
| - if extended_attributes_list:
|
| - extended_string = '[%s] ' % ', '.join(extended_attributes_list)
|
| - else:
|
| - extended_string = ''
|
| -
|
| - attribute_string = 'attribute %(interface_name)sConstructor %(interface_name)s' % {'interface_name': interface_name}
|
| - attributes_list = [extended_string + attribute_string]
|
| -
|
| - # In addition to the regular property, for every [NamedConstructor]
|
| - # extended attribute on an interface, a corresponding property MUST exist
|
| - # on the ECMAScript global object.
|
| - if 'NamedConstructor' in extended_attributes:
|
| - named_constructor = extended_attributes['NamedConstructor']
|
| - # Extract function name, namely everything before opening '('
|
| - constructor_name = re.sub(r'\(.*', '', named_constructor)
|
| - # Note the reduplicated 'ConstructorConstructor'
|
| - attribute_string = 'attribute %sConstructorConstructor %s' % (interface_name, constructor_name)
|
| - attributes_list.append(extended_string + attribute_string)
|
| -
|
| - return attributes_list
|
| -
|
| -
|
| -def generate_event_names_file(destination_filename, event_names, only_if_changed=False):
|
| - source_dir, _ = os.path.split(os.getcwd())
|
| - lines = []
|
| - lines.append('namespace="Event"\n')
|
| - lines.append('\n')
|
| - for filename in event_names:
|
| - attributes = []
|
| - extended_attributes = event_names[filename]
|
| - for key in ('ImplementedAs', 'Conditional', 'EnabledAtRuntime'):
|
| - suffix = ''
|
| - if key == 'EnabledAtRuntime':
|
| - suffix = 'Enabled'
|
| - if key in extended_attributes:
|
| - attributes.append('%s=%s%s' % (key, extended_attributes[key], suffix))
|
| - refined_filename, _ = os.path.splitext(os.path.relpath(filename, source_dir))
|
| - lines.append('%s %s\n' % (refined_filename, ', '.join(attributes)))
|
| - write_file(lines, destination_filename, only_if_changed)
|
| -
|
| -
|
| -def generate_global_constructors_partial_interface(interface_name, destination_filename, constructor_attributes_list, only_if_changed=False):
|
| - lines = []
|
| - lines.append('partial interface %s {\n' % interface_name)
|
| - for constructor_attribute in constructor_attributes_list:
|
| - lines.append(' %s;\n' % constructor_attribute)
|
| - lines.append('};\n')
|
| - write_file(lines, destination_filename, only_if_changed)
|
| -
|
| -
|
| -def parse_idl_files(idl_files, window_constructors_filename, workerglobalscope_constructors_filename, sharedworkerglobalscope_constructors_filename, dedicatedworkerglobalscope_constructors_filename, event_names_file, only_if_changed=False):
|
| - interface_name_to_idl_file = {}
|
| - idl_file_to_interface_name = {}
|
| - supplemental_dependencies = {}
|
| - supplementals = {}
|
| - event_names = {}
|
| - window_constructor_attributes_list = []
|
| - workerglobalscope_constructor_attributes_list = []
|
| - sharedworkerglobalscope_constructor_attributes_list = []
|
| - dedicatedworkerglobalscope_constructor_attributes_list = []
|
| -
|
| - parent_interface = {}
|
| - interface_extended_attribute = {}
|
| - interface_to_file = {}
|
| -
|
| - # Populate interface_name_to_idl_file first
|
| - for idl_file_name in idl_files:
|
| - full_path = os.path.realpath(idl_file_name)
|
| - interface_name, _ = os.path.splitext(os.path.basename(idl_file_name))
|
| - interface_name_to_idl_file[interface_name] = full_path
|
| -
|
| - for idl_file_name in idl_files:
|
| - full_path = os.path.realpath(idl_file_name)
|
| - interface_name, _ = os.path.splitext(os.path.basename(idl_file_name))
|
| - idl_file_contents = get_file_contents(full_path)
|
| -
|
| - if interface_name == 'Event':
|
| - event_names[idl_file_name] = get_interface_extended_attributes_from_idl(idl_file_contents)
|
| - else:
|
| - parent = get_parent_interface(idl_file_contents)
|
| - if parent:
|
| - parent_interface[interface_name] = parent
|
| - interface_extended_attribute[interface_name] = get_interface_extended_attributes_from_idl(idl_file_contents)
|
| - interface_to_file[interface_name] = idl_file_name
|
| -
|
| - # Handle partial interfaces
|
| - partial_interface_name = get_partial_interface_name_from_idl(idl_file_contents)
|
| - if partial_interface_name:
|
| - supplemental_dependencies[full_path] = [partial_interface_name]
|
| - continue
|
| -
|
| - # Parse 'identifier-A implements identifier-B; statements
|
| - implemented_interfaces = get_implemented_interfaces_from_idl(idl_file_contents, interface_name)
|
| - for implemented_interface in implemented_interfaces:
|
| - assert implemented_interface in interface_name_to_idl_file, \
|
| -"Could not find a the IDL file where the following implemented interface is defined: %s" % implemented_interface
|
| - supplemental_dependencies.setdefault(interface_name_to_idl_file[implemented_interface], []).append(interface_name)
|
| - # Handle [NoInterfaceObject]
|
| - if not is_callback_interface_from_idl(idl_file_contents):
|
| - extended_attributes = get_interface_extended_attributes_from_idl(idl_file_contents)
|
| - if 'NoInterfaceObject' not in extended_attributes:
|
| - global_contexts = extended_attributes.get('GlobalContext', 'Window').split('&')
|
| - constructor_list = generate_constructor_attribute_list(interface_name, extended_attributes)
|
| - if 'Window' in global_contexts:
|
| - window_constructor_attributes_list.extend(constructor_list)
|
| - if 'WorkerGlobalScope' in global_contexts:
|
| - workerglobalscope_constructor_attributes_list.extend(constructor_list)
|
| - if 'SharedWorkerGlobalScope' in global_contexts:
|
| - sharedworkerglobalscope_constructor_attributes_list.extend(constructor_list)
|
| - if 'DedicatedWorkerGlobalScope' in global_contexts:
|
| - dedicatedworkerglobalscope_constructor_attributes_list.extend(constructor_list)
|
| - idl_file_to_interface_name[full_path] = interface_name
|
| - supplementals[full_path] = []
|
| -
|
| - for interface in parent_interface:
|
| - parent = parent_interface[interface]
|
| - while parent in parent_interface:
|
| - parent = parent_interface[parent]
|
| - if parent == 'Event':
|
| - event_names[interface_to_file[interface]] = interface_extended_attribute[interface]
|
| - generate_event_names_file(event_names_file, event_names, only_if_changed=only_if_changed)
|
| -
|
| - # Generate Global constructors
|
| - if 'Window' in interface_name_to_idl_file:
|
| - generate_global_constructors_partial_interface("Window", window_constructors_filename, window_constructor_attributes_list, only_if_changed=only_if_changed)
|
| - supplemental_dependencies[window_constructors_filename] = ['Window']
|
| - if 'WorkerGlobalScope' in interface_name_to_idl_file:
|
| - generate_global_constructors_partial_interface("WorkerGlobalScope", workerglobalscope_constructors_filename, workerglobalscope_constructor_attributes_list, only_if_changed=only_if_changed)
|
| - supplemental_dependencies[workerglobalscope_constructors_filename] = ['WorkerGlobalScope']
|
| - if 'SharedWorkerGlobalScope' in interface_name_to_idl_file:
|
| - generate_global_constructors_partial_interface("SharedWorkerGlobalScope", sharedworkerglobalscope_constructors_filename, sharedworkerglobalscope_constructor_attributes_list, only_if_changed=only_if_changed)
|
| - supplemental_dependencies[sharedworkerglobalscope_constructors_filename] = ['SharedWorkerGlobalScope']
|
| - if 'DedicatedWorkerGlobalScope' in interface_name_to_idl_file:
|
| - generate_global_constructors_partial_interface("DedicatedWorkerGlobalScope", dedicatedworkerglobalscope_constructors_filename, dedicatedworkerglobalscope_constructor_attributes_list, only_if_changed=only_if_changed)
|
| - supplemental_dependencies[dedicatedworkerglobalscope_constructors_filename] = ['DedicatedWorkerGlobalScope']
|
| -
|
| - # Resolve partial interfaces dependencies
|
| - for idl_file, base_files in supplemental_dependencies.iteritems():
|
| - for base_file in base_files:
|
| - target_idl_file = interface_name_to_idl_file[base_file]
|
| - supplementals[target_idl_file].append(idl_file)
|
| - if idl_file in supplementals:
|
| - # Should never occur. Might be needed in corner cases.
|
| - del supplementals[idl_file]
|
| - return supplementals
|
| -
|
| -
|
| -def write_dependency_file(filename, supplementals, only_if_changed=False):
|
| - """Outputs the dependency file.
|
| -
|
| - The format of a supplemental dependency file:
|
| -
|
| - Window.idl P.idl Q.idl R.idl
|
| - Document.idl S.idl
|
| - Event.idl
|
| - ...
|
| -
|
| - The above indicates that:
|
| - Window.idl is supplemented by P.idl, Q.idl and R.idl,
|
| - Document.idl is supplemented by S.idl, and
|
| - Event.idl is supplemented by no IDLs.
|
| -
|
| - An IDL that supplements another IDL (e.g. P.idl) does not have its own
|
| - lines in the dependency file.
|
| - """
|
| - lines = []
|
| - for idl_file, supplemental_files in sorted(supplementals.iteritems()):
|
| - lines.append('%s %s\n' % (idl_file, ' '.join(supplemental_files)))
|
| - write_file(lines, filename, only_if_changed)
|
| -
|
| -
|
| -def main():
|
| - options = parse_options()
|
| - idl_files = []
|
| - with open(options.idl_files_list) as idl_files_list_file:
|
| - for line in idl_files_list_file:
|
| - idl_files.append(string.rstrip(line, '\n'))
|
| - resolved_supplementals = parse_idl_files(idl_files, options.window_constructors_file, options.workerglobalscope_constructors_file, options.sharedworkerglobalscope_constructors_file, options.dedicatedworkerglobalscope_constructors_file, options.event_names_file, only_if_changed=options.write_file_only_if_changed)
|
| - write_dependency_file(options.supplemental_dependency_file, resolved_supplementals, only_if_changed=options.write_file_only_if_changed)
|
| -
|
| -
|
| -if __name__ == '__main__':
|
| - main()
|
|
|