Commit 9732e8ca authored by nbarth@chromium.org's avatar nbarth@chromium.org

Split generate_event_interfaces.py from compute_interfaces_info.py

This is the last step in factoring compute_interfaces_info:
EventInterfaces.in is a simple auxiliary file that's largely unrelated to
bindings.
Splitting it out means compute_interfaces_info now purely computes interfaces
info!
This means we can reuse it without needing dummy files (e.g., in r-b-t and in
gyp), and also simplifies its code.

We can actually simplify both scripts (and r-b-t) further,
but this is a conservative CL, just splitting it out.

BUG=341748
R=haraken

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

git-svn-id: svn://svn.chromium.org/blink/trunk@168499 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent d700b9d7
......@@ -235,7 +235,6 @@
],
'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/blink/InterfacesInfo.pickle',
'<(SHARED_INTERMEDIATE_DIR)/blink/EventInterfaces.in',
],
'action': [
'python',
......@@ -244,14 +243,41 @@
'<(static_idl_files_list)',
'--interfaces-info-file',
'<(SHARED_INTERMEDIATE_DIR)/blink/InterfacesInfo.pickle',
'--event-names-file',
'<(SHARED_INTERMEDIATE_DIR)/blink/EventInterfaces.in',
'<@(write_file_only_if_changed)',
'--',
# Generated files must be passed at command line
'<@(generated_idl_files)',
],
'message': 'Computing global information about IDL files, and generating list of Event interfaces',
'message': 'Computing global information about IDL files',
}]
},
################################################################################
{
'target_name': 'event_interfaces',
'type': 'none',
'dependencies': [
'interfaces_info',
],
'actions': [{
'action_name': 'generate_event_interfaces',
'inputs': [
'scripts/generate_event_interfaces.py',
'scripts/utilities.py',
'<(SHARED_INTERMEDIATE_DIR)/blink/InterfacesInfo.pickle',
],
'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/blink/EventInterfaces.in',
],
'action': [
'python',
'scripts/generate_event_interfaces.py',
'--interfaces-info-file',
'<(SHARED_INTERMEDIATE_DIR)/blink/InterfacesInfo.pickle',
'--event-names-file',
'<(SHARED_INTERMEDIATE_DIR)/blink/EventInterfaces.in',
'<@(write_file_only_if_changed)',
],
'message': 'Generating list of Event interfaces',
}]
},
################################################################################
......@@ -369,6 +395,7 @@
'type': 'none',
'dependencies': [
'aggregate_generated_bindings',
'event_interfaces',
'individual_generated_bindings',
],
},
......
......@@ -73,8 +73,6 @@ Note that all of these are stable information, unlikely to change without
moving or deleting files (hence requiring a full rebuild anyway) or significant
code changes (for inherited extended attributes).
FIXME: also generates EventNames.in; factor out. http://crbug.com/341748
Design doc: http://www.chromium.org/developers/design-documents/idl-build
"""
......@@ -83,7 +81,7 @@ import os
import posixpath
import sys
from utilities import get_file_contents, write_file, 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_implemented_interfaces_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))
......@@ -111,13 +109,11 @@ class IdlInterfaceFileNotFoundError(Exception):
def parse_options():
usage = 'Usage: %prog [options] [generated1.idl]...'
parser = optparse.OptionParser(usage=usage)
parser.add_option('--event-names-file', help='output file')
parser.add_option('--idl-files-list', help='file listing IDL files')
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')
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.interfaces_info_file is None:
parser.error('Must specify an output file using --interfaces-info-file.')
if options.idl_files_list is None:
......@@ -128,46 +124,6 @@ def parse_options():
return options, args
################################################################################
# Write files
################################################################################
def write_event_names_file(destination_filename, only_if_changed):
# Generate event names for all interfaces that inherit from Event,
# including Event itself.
# FIXME: factor out. http://crbug.com/341748
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':
value += 'Enabled'
return name + '=' + value
source_dir, _ = os.path.split(os.getcwd())
lines = []
lines.append('namespace="Event"\n')
lines.append('\n')
for filename, extended_attributes in sorted(
(interface_info['full_path'],
extended_attributes_by_interface[interface_name])
for interface_name, interface_info in interfaces_info.iteritems()
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_attribute_string(name)
for name in 'Conditional', 'ImplementedAs', 'RuntimeEnabled'
if name in extended_attributes]
lines.append('%s %s\n' % (refined_filename, ', '.join(extended_attributes_list)))
write_file(lines, destination_filename, only_if_changed)
################################################################################
# Computations
################################################################################
......@@ -329,10 +285,10 @@ def main():
# cannot be included in the file listing static files
idl_files.extend(args)
only_if_changed = options.write_file_only_if_changed
compute_interfaces_info(idl_files)
write_pickle_file(options.interfaces_info_file, interfaces_info, only_if_changed)
write_event_names_file(options.event_names_file, only_if_changed)
write_pickle_file(options.interfaces_info_file,
interfaces_info,
options.write_file_only_if_changed)
if __name__ == '__main__':
......
#!/usr/bin/python
#
# 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.
"""Generate event interfaces .in file (EventInterfaces.in).
The event interfaces .in file contains a list of all Event interfaces, i.e.,
all interfaces that inherit from Event, including Event itself,
together with certain extended attributes.
This list is used in core/ to generate EventFactory and EventNames.
The .in format is documented in build/scripts/in_file.py.
"""
import optparse
import cPickle as pickle
import os
import posixpath
import sys
from utilities import get_file_contents, write_file, get_interface_extended_attributes_from_idl
interfaces_info = {}
extended_attributes_by_interface = {} # interface name -> extended attributes
def parse_options():
parser = optparse.OptionParser()
parser.add_option('--event-names-file', help='output 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')
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.interfaces_info_file is None:
parser.error('Must specify an input file using --interfaces-info-file.')
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 allowed, but %d given.' % len(args))
return options
def store_event_extended_attributes():
event_interfaces = 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')))
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):
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':
value += 'Enabled'
return name + '=' + value
source_dir, _ = os.path.split(os.getcwd())
lines = []
lines.append('namespace="Event"\n')
lines.append('\n')
for filename, extended_attributes in sorted(
(interface_info['full_path'],
extended_attributes_by_interface[interface_name])
for interface_name, interface_info in interfaces_info.iteritems()
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_attribute_string(name)
for name in 'Conditional', 'ImplementedAs', 'RuntimeEnabled'
if name in extended_attributes]
lines.append('%s %s\n' % (refined_filename, ', '.join(extended_attributes_list)))
write_file(lines, destination_filename, only_if_changed)
################################################################################
def main():
options = parse_options()
with open(options.interfaces_info_file) as interfaces_info_file:
interfaces_info.update(pickle.load(interfaces_info_file))
store_event_extended_attributes()
write_event_names_file(options.event_names_file,
options.write_file_only_if_changed)
if __name__ == '__main__':
sys.exit(main())
......@@ -146,13 +146,19 @@ class BindingsTests(object):
os.write(list_file, list_contents)
return list_filename
def compute_interfaces_info(idl_files_list_filename,
event_names_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):
cmd = ['python',
'bindings/scripts/compute_interfaces_info.py',
'--idl-files-list', idl_files_list_filename,
'--interfaces-info-file', self.interfaces_info_filename,
'--event-names-file', event_names_filename,
'--write-file-only-if-changed', '0']
self.run_command(cmd)
......@@ -164,8 +170,8 @@ class BindingsTests(object):
try:
# We first compute interfaces info for testing files only,
# so we can compare EventInterfaces.in.
compute_interfaces_info(test_idl_files_list_filename,
self.event_names_filename)
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
......@@ -178,9 +184,7 @@ class BindingsTests(object):
# computing dependencies for the real Node.idl file.
#
# Don't overwrite the event names file generated for testing IDLs
_, dummy_event_names_filename = self.provider.new_temp_file()
compute_interfaces_info(all_idl_files_list_filename,
dummy_event_names_filename)
compute_interfaces_info(all_idl_files_list_filename)
except ScriptError, e:
print 'ERROR: compute_interfaces_info.py'
print e.output
......
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