blob: 659fd8610052996694e37a86ecef68015e2f1caa [file] [log] [blame]
#!/usr/bin/python
# Copyright (C) 2010 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:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. 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.
#
# THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 traceback
import fnmatch
from optparse import OptionParser
import os
import shutil
import sys
import tempfile
import compute_interfaces_info_individual
from compute_interfaces_info_individual import compute_info_individual, info_individual
import compute_interfaces_info_overall
from compute_interfaces_info_overall import compute_interfaces_info_overall, interfaces_info
from compiler import IdlCompilerDart
# TODO(terry): Temporary solution list of IDLs to parse and IDL as dependencies.
from idl_files import full_path_core_idl_files,\
full_path_core_dependency_idl_files,\
full_path_modules_idl_files,\
full_path_modules_dependency_idl_files,\
full_path_core_dictionary_idl_files,\
full_path_modules_dictionary_idl_files
#from dart_tests import run_dart_tests
EXTENDED_ATTRIBUTES_FILE = 'bindings/IDLExtendedAttributes.txt'
idl_compiler = None
def parse_options():
parser = OptionParser()
parser.add_option("--output-directory",
action="store",
type="string",
dest="output_directory",
help="Generate output to a known directory")
parser.add_option("-v", "--verbose",
action="store_true",
dest="verbose",
default=False,
help="Show all information messages")
parser.add_option("-k", "--keep",
action="store_true",
dest="keep",
default=False,
help="Don't delete the temporary directory on exit")
parser.add_option("--compute-idls", type='int', help="Compile IDLs interfaces and dependencies (GYP)")
parser.add_option('--globals-only', type='int', help="Generate the globals")
options, args = parser.parse_args()
options.compute_idls = bool(options.compute_idls)
options.globals_only = bool(options.globals_only)
return options
class ScopedTempFileProvider(object):
def __init__(self, keep=False):
self.keep = keep
self.dir_paths = []
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
if not self.keep:
for dir_path in self.dir_paths:
# Temporary directories are used as output directories, so they
# contains unknown files (they aren't empty), hence use rmtree
shutil.rmtree(dir_path)
def new_temp_dir(self):
dir_path = tempfile.mkdtemp()
self.dir_paths.append(dir_path)
return dir_path
class DirectoryProvider(object):
def __init__(self, path=""):
self.dir_path = path
def __enter__(self):
return self
def new_temp_dir(self):
return self.dir_path
def idl_paths_recursive(directory):
idl_paths = []
for dirpath, _, files in os.walk(directory):
idl_paths.extend(os.path.join(dirpath, filename)
for filename in fnmatch.filter(files, '*.idl'))
return idl_paths
class Build():
def __init__(self, provider):
self.output_directory = provider.new_temp_dir()
attrib_file = os.path.join('Source', EXTENDED_ATTRIBUTES_FILE)
# Create compiler.
self.idl_compiler = IdlCompilerDart(self.output_directory,
attrib_file,
interfaces_info=interfaces_info,
only_if_changed=True)
def format_exception(self, e):
exception_list = traceback.format_stack()
exception_list = exception_list[:-2]
exception_list.extend(traceback.format_tb(sys.exc_info()[2]))
exception_list.extend(traceback.format_exception_only(sys.exc_info()[0], sys.exc_info()[1]))
exception_str = "Traceback (most recent call last):\n"
exception_str += "".join(exception_list)
# Removing the last \n
exception_str = exception_str[:-1]
return exception_str
def generate_from_idl(self, idl_file):
try:
idl_file_fullpath = os.path.realpath(idl_file)
self.idl_compiler.compile_file(idl_file_fullpath)
except Exception as err:
print 'ERROR: idl_compiler.py: ' + os.path.basename(idl_file)
print err
print
print 'Stack Dump:'
print self.format_exception(err)
return 1
def generate_global(self):
try:
self.idl_compiler.generate_global()
except Exception as err:
print 'ERROR: idl_compiler.py generate global'
print err
print
print 'Stack Dump:'
print self.format_exception(err)
return 1
return 0
def main(argv):
'''
Runs Dart IDL code generator; IDL files. IDL files same as GYP files in
Source/bindings/core/core.gypi and Source/bindings/modules/modules.gypi (see
idl_files.py on list of files).
To run the PYTHONPATH should have the directories:
Source/bindings/scripts
Source/bindings/scripts/dart
'''
options = parse_options()
if options.compute_idls:
# TODO(terry): Assumes CWD is third_party/WebKit so any call to
# full_path_NNNN is prefixing 'Source/core' to path.
core_idls = full_path_core_idl_files()
core_dependency_idls = full_path_core_dependency_idl_files()
modules_idls = full_path_modules_idl_files()
modules_dependency_idls = full_path_modules_dependency_idl_files()
core_dictionary_idls = full_path_core_dictionary_idl_files()
modules_dictionary_idls = full_path_modules_dictionary_idl_files()
all_interfaces = core_idls + modules_idls
all_dependencies = core_dependency_idls + modules_dependency_idls
all_dictionaries = core_dictionary_idls + modules_dictionary_idls
all_files = all_interfaces + all_dependencies + all_dictionaries
# 2-stage computation: individual, then overall
for idl_filename in all_files:
compute_info_individual(idl_filename)
info_individuals = [info_individual()]
compute_interfaces_info_overall(info_individuals)
# Compile just IDLs with interfaces (no dependencies).
if (options.output_directory == None):
with ScopedTempFileProvider(keep=options.keep) as provider:
build = Build(provider)
else:
provider = DirectoryProvider(path=options.output_directory)
build = Build(provider)
if options.verbose and options.keep:
print 'Output directory %s created' % build.output_directory
# Compile IDLs
for filename in (all_dictionaries + all_interfaces):
if not filename.endswith('.idl'):
continue
if build.generate_from_idl(filename):
return False
if options.verbose:
print '%s IDLs with interfaces processed' % len(all_interfaces)
if options.verbose and not options.keep:
print 'Output directory %s deleted' % build.output_directory
if options.globals_only:
if (options.output_directory == None):
with ScopedTempFileProvider(keep=options.keep) as provider:
build = Build(provider)
else:
provider = DirectoryProvider(path=options.output_directory)
build = Build(provider)
if options.verbose:
print 'Generating global...'
build.generate_global()
if options.verbose:
print 'Created DartWebkitClassIds .h/.cpp'
if __name__ == '__main__':
sys.exit(main(sys.argv))