Commit 735d1b3d authored by nbarth@chromium.org's avatar nbarth@chromium.org

Clean up generate_event_interfaces.py

Follow-up to the split CL.
Just clean-up, no changes to generated EventInterfaces.in.

* Rename to generate_event_interfaces (from "*_names")
This is b/c:
- the output file is called EventInterfaces.in
- the output file is used for both EventFactory and EventNames

* Remove EventInterfaces.in from run-bindings-tests
This file is useless, and adds unnecessary complexity to r-b-t.
The actual output file is trivial:
namespace="Event"

Source/bindings/tests/idls/TestInterfaceEventConstructor
...and I've never looked at it during CG changes.

With it, we need to have 2 passes of compute_interfaces_info,
and a separate temporary file.
Without it, once Terry's CL lands, we'll have no individual files,
and we can just use one temporary directory, removing lots of
temp file complexity.

* Compute source_dir robustly (not using getcwd)

* Refactoring and renaming

Follow-up to:
Split generate_event_interfaces.py from compute_interfaces_info.py
https://codereview.chromium.org/185303008/

BUG=341748
R=haraken

Review URL: https://codereview.chromium.org/186433003

git-svn-id: svn://svn.chromium.org/blink/trunk@168599 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent dec13972
...@@ -272,7 +272,7 @@ ...@@ -272,7 +272,7 @@
'scripts/generate_event_interfaces.py', 'scripts/generate_event_interfaces.py',
'--interfaces-info-file', '--interfaces-info-file',
'<(SHARED_INTERMEDIATE_DIR)/blink/InterfacesInfo.pickle', '<(SHARED_INTERMEDIATE_DIR)/blink/InterfacesInfo.pickle',
'--event-names-file', '--event-interfaces-file',
'<(SHARED_INTERMEDIATE_DIR)/blink/EventInterfaces.in', '<(SHARED_INTERMEDIATE_DIR)/blink/EventInterfaces.in',
'<@(write_file_only_if_changed)', '<@(write_file_only_if_changed)',
], ],
......
...@@ -34,11 +34,13 @@ The event interfaces .in file contains a list of all Event interfaces, i.e., ...@@ -34,11 +34,13 @@ The event interfaces .in file contains a list of all Event interfaces, i.e.,
all interfaces that inherit from Event, including Event itself, all interfaces that inherit from Event, including Event itself,
together with certain extended attributes. together with certain extended attributes.
Paths are in POSIX format, and relative to Source/.
This list is used in core/ to generate EventFactory and EventNames. This list is used in core/ to generate EventFactory and EventNames.
The .in format is documented in build/scripts/in_file.py. The .in format is documented in build/scripts/in_file.py.
""" """
import optparse from optparse import OptionParser
import cPickle as pickle import cPickle as pickle
import os import os
import posixpath import posixpath
...@@ -46,19 +48,24 @@ import sys ...@@ -46,19 +48,24 @@ import sys
from utilities import get_file_contents, write_file, get_interface_extended_attributes_from_idl from utilities import get_file_contents, write_file, get_interface_extended_attributes_from_idl
interfaces_info = {} EXPORTED_EXTENDED_ATTRIBUTES = (
extended_attributes_by_interface = {} # interface name -> extended attributes 'Conditional',
'ImplementedAs',
'RuntimeEnabled',
)
module_path = os.path.dirname(os.path.realpath(__file__))
source_dir = os.path.normpath(os.path.join(module_path, os.pardir, os.pardir))
def parse_options(): def parse_options():
parser = optparse.OptionParser() parser = OptionParser()
parser.add_option('--event-names-file', help='output file') parser.add_option('--event-interfaces-file', help='output file')
parser.add_option('--interfaces-info-file', help='output pickle file') parser.add_option('--interfaces-info-file', help='output pickle 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') 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() options, args = parser.parse_args()
if options.event_names_file is None: if options.event_interfaces_file is None:
parser.error('Must specify an output file using --event-names-file.') parser.error('Must specify an output file using --event-interfaces-file.')
if options.interfaces_info_file is None: if options.interfaces_info_file is None:
parser.error('Must specify an input file using --interfaces-info-file.') parser.error('Must specify an input file using --interfaces-info-file.')
if options.write_file_only_if_changed is None: if options.write_file_only_if_changed is None:
...@@ -69,49 +76,42 @@ def parse_options(): ...@@ -69,49 +76,42 @@ def parse_options():
return options return options
def store_event_extended_attributes(): def write_event_interfaces_file(interfaces_info, destination_filename, only_if_changed):
# Event interfaces are interfaces that inherit from Event, and Event itself
event_interfaces = set( event_interfaces = set(
interface_name interface_name
for interface_name, interface_info in interfaces_info.iteritems() for interface_name, interface_info in interfaces_info.iteritems()
if (interface_name == 'Event' or if (interface_name == 'Event' or
('ancestors' in interface_info and ('ancestors' in interface_info and
interface_info['ancestors'][-1] == 'Event'))) interface_info['ancestors'][-1] == 'Event')))
for interface_name in event_interfaces:
interface_info = interfaces_info[interface_name]
idl_file_contents = get_file_contents(interface_info['full_path'])
extended_attributes_by_interface[interface_name] = get_interface_extended_attributes_from_idl(idl_file_contents)
def write_event_names_file(destination_filename, only_if_changed): def extended_attribute_string(name, value):
event_names = set(
interface_name
for interface_name, interface_info in interfaces_info.iteritems()
if (interface_name == 'Event' or
('ancestors' in interface_info and
interface_info['ancestors'][-1] == 'Event')))
def extended_attribute_string(name):
value = extended_attributes[name]
if name == 'RuntimeEnabled': if name == 'RuntimeEnabled':
value += 'Enabled' value += 'Enabled'
return name + '=' + value return name + '=' + value
source_dir, _ = os.path.split(os.getcwd()) def interface_line(interface_name):
lines = [] full_path = interfaces_info[interface_name]['full_path']
lines.append('namespace="Event"\n')
lines.append('\n') relative_path_local, _ = os.path.splitext(os.path.relpath(full_path, source_dir))
for filename, extended_attributes in sorted( relative_path_posix = relative_path_local.replace(os.sep, posixpath.sep)
(interface_info['full_path'],
extended_attributes_by_interface[interface_name]) idl_file_contents = get_file_contents(full_path)
for interface_name, interface_info in interfaces_info.iteritems() extended_attributes = get_interface_extended_attributes_from_idl(idl_file_contents)
if interface_name in event_names):
refined_filename, _ = os.path.splitext(os.path.relpath(filename, source_dir))
refined_filename = refined_filename.replace(os.sep, posixpath.sep)
extended_attributes_list = [ extended_attributes_list = [
extended_attribute_string(name) extended_attribute_string(name, extended_attributes[name])
for name in 'Conditional', 'ImplementedAs', 'RuntimeEnabled' for name in EXPORTED_EXTENDED_ATTRIBUTES
if name in extended_attributes] if name in extended_attributes]
lines.append('%s %s\n' % (refined_filename, ', '.join(extended_attributes_list)))
return '%s %s\n' % (relative_path_posix,
', '.join(extended_attributes_list))
lines = ['namespace="Event"\n',
'\n']
interface_lines = [interface_line(interface_name)
for interface_name in event_interfaces]
interface_lines.sort()
lines.extend(interface_lines)
write_file(lines, destination_filename, only_if_changed) write_file(lines, destination_filename, only_if_changed)
...@@ -120,10 +120,10 @@ def write_event_names_file(destination_filename, only_if_changed): ...@@ -120,10 +120,10 @@ def write_event_names_file(destination_filename, only_if_changed):
def main(): def main():
options = parse_options() options = parse_options()
with open(options.interfaces_info_file) as interfaces_info_file: with open(options.interfaces_info_file) as interfaces_info_file:
interfaces_info.update(pickle.load(interfaces_info_file)) interfaces_info = pickle.load(interfaces_info_file)
store_event_extended_attributes() write_event_interfaces_file(interfaces_info,
write_event_names_file(options.event_names_file, options.event_interfaces_file,
options.write_file_only_if_changed) options.write_file_only_if_changed)
if __name__ == '__main__': if __name__ == '__main__':
......
namespace="Event"
Source/bindings/tests/idls/TestInterfaceEventConstructor
...@@ -57,7 +57,6 @@ DEPENDENCY_IDL_FILES = set([ ...@@ -57,7 +57,6 @@ DEPENDENCY_IDL_FILES = set([
all_input_directory = '.' # Relative to Source/ all_input_directory = '.' # Relative to Source/
test_input_directory = os.path.join('bindings', 'tests', 'idls') test_input_directory = os.path.join('bindings', 'tests', 'idls')
reference_directory = os.path.join('bindings', 'tests', 'results') reference_directory = os.path.join('bindings', 'tests', 'results')
reference_event_names_filename = os.path.join(reference_directory, 'EventInterfaces.in')
class ScopedTempFileProvider(object): class ScopedTempFileProvider(object):
...@@ -104,7 +103,6 @@ class BindingsTests(object): ...@@ -104,7 +103,6 @@ class BindingsTests(object):
self.output_directory = reference_directory self.output_directory = reference_directory
else: else:
self.output_directory = provider.new_temp_dir() self.output_directory = provider.new_temp_dir()
self.event_names_filename = os.path.join(self.output_directory, 'EventInterfaces.in')
def run_command(self, cmd): def run_command(self, cmd):
output = self.executive.run_command(cmd) output = self.executive.run_command(cmd)
...@@ -146,14 +144,6 @@ class BindingsTests(object): ...@@ -146,14 +144,6 @@ class BindingsTests(object):
os.write(list_file, list_contents) os.write(list_file, list_contents)
return list_filename return list_filename
def generate_event_interfaces(event_names_filename):
cmd = ['python',
'bindings/scripts/generate_event_interfaces.py',
'--interfaces-info-file', self.interfaces_info_filename,
'--event-names-file', event_names_filename,
'--write-file-only-if-changed', '0']
self.run_command(cmd)
def compute_interfaces_info(idl_files_list_filename): def compute_interfaces_info(idl_files_list_filename):
cmd = ['python', cmd = ['python',
'bindings/scripts/compute_interfaces_info.py', 'bindings/scripts/compute_interfaces_info.py',
...@@ -162,28 +152,18 @@ class BindingsTests(object): ...@@ -162,28 +152,18 @@ class BindingsTests(object):
'--write-file-only-if-changed', '0'] '--write-file-only-if-changed', '0']
self.run_command(cmd) self.run_command(cmd)
test_idl_files_list_filename = write_list_file(idl_paths(test_input_directory)) # We compute interfaces info for *all* IDL files, not just test IDL
# files, as code generator output depends on inheritance (both ancestor
# chain and inherited extended attributes), and some real interfaces
# are special-cased, such as Node.
#
# For example, when testing the behavior of interfaces that inherit
# from Node, we also need to know that these inherit from EventTarget,
# since this is also special-cased and Node inherits from EventTarget,
# but this inheritance information requires computing dependencies for
# the real Node.idl file.
all_idl_files_list_filename = write_list_file(idl_paths_recursive(all_input_directory)) all_idl_files_list_filename = write_list_file(idl_paths_recursive(all_input_directory))
if self.reset_results and self.verbose:
print 'Reset results: EventInterfaces.in'
try: try:
# We first compute interfaces info for testing files only,
# so we can compare EventInterfaces.in.
compute_interfaces_info(test_idl_files_list_filename)
generate_event_interfaces(self.event_names_filename)
# We then compute interfaces info for all IDL files, as code
# generator output depends on inheritance (both ancestor chain and
# inherited extended attributes), and some real interfaces are
# special-cased, such as Node.
# For example, when testing the behavior of interfaces that inherit
# from Node, we also need to know that these inherit from
# EventTarget, since this is also special-cased and Node inherits
# from EventTarget, but this inheritance information requires
# computing dependencies for the real Node.idl file.
#
# Don't overwrite the event names file generated for testing IDLs
compute_interfaces_info(all_idl_files_list_filename) compute_interfaces_info(all_idl_files_list_filename)
except ScriptError, e: except ScriptError, e:
print 'ERROR: compute_interfaces_info.py' print 'ERROR: compute_interfaces_info.py'
...@@ -223,7 +203,6 @@ class BindingsTests(object): ...@@ -223,7 +203,6 @@ class BindingsTests(object):
def no_excess_files(self): def no_excess_files(self):
generated_files = set(os.listdir(self.output_directory)) generated_files = set(os.listdir(self.output_directory))
generated_files.add('.svn') # Subversion working copy directory generated_files.add('.svn') # Subversion working copy directory
generated_files.add('EventInterfaces.in') # only in Perl, not Python
excess_files = [output_file excess_files = [output_file
for output_file in os.listdir(reference_directory) for output_file in os.listdir(reference_directory)
if output_file not in generated_files] if output_file not in generated_files]
...@@ -255,9 +234,7 @@ class BindingsTests(object): ...@@ -255,9 +234,7 @@ class BindingsTests(object):
print 'Reset results: %s' % input_filename print 'Reset results: %s' % input_filename
# Detect all changes # Detect all changes
passed = self.identical_file(reference_event_names_filename, passed = self.identical_output_files()
self.event_names_filename)
passed &= self.identical_output_files()
passed &= self.no_excess_files() passed &= self.no_excess_files()
return passed return passed
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment