blob: 914b7ca552e53b83c5f37f84659214bef26de943 [file] [log] [blame]
#!/usr/bin/python
# Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
"""This is the entry point to create Dart APIs from the IDL database."""
import dartgenerator
import database
import fremontcutbuilder
import logging.config
import monitored
import multiemitter
import optparse
import os
import shutil
import subprocess
import sys
from generator import TypeRegistry
from htmleventgenerator import HtmlEventGenerator
from htmlrenamer import HtmlRenamer
from systemhtml import DartLibraryEmitter, Dart2JSBackend,\
HtmlDartInterfaceGenerator, DartLibrary, DartLibraries,\
HTML_LIBRARY_NAMES
from systemnative import CPPLibraryEmitter, DartiumBackend
from templateloader import TemplateLoader
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..'))
import utils
_logger = logging.getLogger('dartdomgenerator')
class GeneratorOptions(object):
def __init__(self, templates, database, type_registry, renamer):
self.templates = templates
self.database = database
self.type_registry = type_registry
self.renamer = renamer
def LoadDatabase(database_dir, use_database_cache):
common_database = database.Database(database_dir)
if use_database_cache:
common_database.LoadFromCache()
else:
common_database.Load()
return common_database
def GenerateFromDatabase(common_database, dart2js_output_dir,
dartium_output_dir):
current_dir = os.path.dirname(__file__)
auxiliary_dir = os.path.join(current_dir, '..', 'src')
template_dir = os.path.join(current_dir, '..', 'templates')
generator = dartgenerator.DartGenerator()
generator.LoadAuxiliary(auxiliary_dir)
generator.FilterMembersWithUnidentifiedTypes(common_database)
webkit_database = common_database.Clone()
# Generate Dart interfaces for the WebKit DOM.
generator.FilterInterfaces(database = webkit_database,
or_annotations = ['WebKit', 'Dart'],
exclude_displaced = ['WebKit'],
exclude_suppressed = ['WebKit', 'Dart'])
generator.FixEventTargets(webkit_database)
generator.AddMissingArguments(webkit_database)
emitters = multiemitter.MultiEmitter()
renamer = HtmlRenamer(webkit_database)
type_registry = TypeRegistry(webkit_database, renamer)
def RunGenerator(dart_libraries, dart_output_dir,
template_loader, backend_factory):
options = GeneratorOptions(
template_loader, webkit_database, type_registry, renamer)
dart_library_emitter = DartLibraryEmitter(
emitters, dart_output_dir, dart_libraries)
event_generator = HtmlEventGenerator(webkit_database, renamer,
template_loader)
def generate_interface(interface):
backend = backend_factory(interface)
interface_generator = HtmlDartInterfaceGenerator(
options, dart_library_emitter, event_generator, interface, backend)
interface_generator.Generate()
generator.Generate(webkit_database, common_database, generate_interface)
dart_library_emitter.EmitLibraries(auxiliary_dir)
if dart2js_output_dir:
template_paths = ['html/dart2js', 'html/impl', 'html/interface', '']
template_loader = TemplateLoader(template_dir,
template_paths,
{'DARTIUM': False, 'DART2JS': True})
backend_options = GeneratorOptions(
template_loader, webkit_database, type_registry, renamer)
backend_factory = lambda interface:\
Dart2JSBackend(interface, backend_options)
dart_output_dir = os.path.join(dart2js_output_dir, 'dart')
dart_libraries = DartLibraries(
HTML_LIBRARY_NAMES, template_loader, 'dart2js', dart2js_output_dir)
RunGenerator(dart_libraries, dart_output_dir,
template_loader, backend_factory)
if dartium_output_dir:
template_paths = ['html/dartium', 'html/impl', 'html/interface', '']
template_loader = TemplateLoader(template_dir,
template_paths,
{'DARTIUM': True, 'DART2JS': False})
backend_options = GeneratorOptions(
template_loader, webkit_database, type_registry, renamer)
cpp_output_dir = os.path.join(dartium_output_dir, 'cpp')
cpp_library_emitter = CPPLibraryEmitter(emitters, cpp_output_dir)
backend_factory = lambda interface:\
DartiumBackend(interface, cpp_library_emitter, backend_options)
dart_output_dir = os.path.join(dartium_output_dir, 'dart')
dart_libraries = DartLibraries(
HTML_LIBRARY_NAMES, template_loader, 'dartium', dartium_output_dir)
RunGenerator(dart_libraries, dart_output_dir,
template_loader, backend_factory)
cpp_library_emitter.EmitDerivedSources(
template_loader.Load('cpp_derived_sources.template'),
dartium_output_dir)
cpp_library_emitter.EmitResolver(
template_loader.Load('cpp_resolver.template'), dartium_output_dir)
_logger.info('Flush...')
emitters.Flush()
monitored.FinishMonitoring(dart2js_output_dir)
def GenerateSingleFile(library_path, output_dir, generated_output_dir=None):
library_dir = os.path.dirname(library_path)
library_filename = os.path.basename(library_path)
copy_dart_script = os.path.relpath('../../copy_dart.py',
library_dir)
output_dir = os.path.relpath(output_dir, library_dir)
command = ' '.join(['cd', library_dir, ';',
copy_dart_script, output_dir, library_filename])
subprocess.call([command], shell=True)
def main():
parser = optparse.OptionParser()
parser.add_option('--parallel', dest='parallel',
action='store_true', default=False,
help='Use fremontcut in parallel mode.')
parser.add_option('--rebuild', dest='rebuild',
action='store_true', default=False,
help='Rebuild the database from IDL using fremontcut.')
parser.add_option('--systems', dest='systems',
action='store', type='string',
default='htmldart2js,htmldartium',
help='Systems to generate (htmldart2js, htmldartium)')
parser.add_option('--output-dir', dest='output_dir',
action='store', type='string',
default=None,
help='Directory to put the generated files')
parser.add_option('--use-database-cache', dest='use_database_cache',
action='store_true',
default=False,
help='''Use the cached database from the previous run to
improve startup performance''')
(options, args) = parser.parse_args()
current_dir = os.path.dirname(__file__)
database_dir = os.path.join(current_dir, '..', 'database')
logging.config.fileConfig(os.path.join(current_dir, 'logging.conf'))
systems = options.systems.split(',')
output_dir = options.output_dir or os.path.join(
current_dir, '..', '..', utils.GetBuildDir(utils.GuessOS(), None),
'generated')
dart2js_output_dir = None
if 'htmldart2js' in systems:
dart2js_output_dir = os.path.join(output_dir, 'dart2js')
dartium_output_dir = None
if 'htmldartium' in systems:
dartium_output_dir = os.path.join(output_dir, 'dartium')
if options.rebuild:
# Parse the IDL and create the database.
database = fremontcutbuilder.main(options.parallel)
else:
# Load the previously generated database.
database = LoadDatabase(database_dir, options.use_database_cache)
GenerateFromDatabase(database, dart2js_output_dir, dartium_output_dir)
if 'htmldart2js' in systems:
_logger.info('Generating dart2js single files.')
for library_name in HTML_LIBRARY_NAMES:
GenerateSingleFile(
os.path.join(dart2js_output_dir, '%s_dart2js.dart' % library_name),
os.path.join('..', '..', '..', 'sdk', 'lib', library_name, 'dart2js'))
if 'htmldartium' in systems:
_logger.info('Generating dartium single files.')
for library_name in HTML_LIBRARY_NAMES:
GenerateSingleFile(
os.path.join(dartium_output_dir, '%s_dartium.dart' % library_name),
os.path.join('..', '..', '..', 'sdk', 'lib', library_name, 'dartium'))
if __name__ == '__main__':
sys.exit(main())