blob: 944d36a412d71d7c6b60a86644587e91c99672ac [file] [log] [blame]
#!/usr/bin/env python3
# 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 css_code_generator
import os
import sys
# Setup all paths to find our PYTHON code
# dart_dir is the location of dart's enlistment dartium (dartium-git/src/dart)
# and Dart (dart-git/dart).
dart_dir = os.path.abspath(
os.path.normpath(os.path.join(os.path.dirname(__file__), '..', '..', '..')))
sys.path.insert(1, os.path.join(dart_dir, 'tools/dom/new_scripts'))
sys.path.insert(1, os.path.join(dart_dir,
'third_party/WebCore/bindings/scripts'))
# Dartium's third_party directory location is dartium-git/src/third_party
# and Dart's third_party directory location is dart-git/dart/third_party.
third_party_dir = os.path.join(dart_dir, 'third_party')
ply_dir = os.path.join(third_party_dir, 'ply')
# If ply directory found then we're a Dart enlistment; third_party location
# is dart-git/dart/third_party
if not os.path.exists(ply_dir):
# For Dartium (ply directory is dartium-git/src/third_party/ply) third_party
# location is dartium-git/src/third_party
third_party_dir = os.path.join(dart_dir, '..', 'third_party')
assert (os.path.exists(third_party_dir))
else:
# It's Dart we need to make sure that tools in injected in our search path
# because this is where idl_parser is located for a Dart enlistment. Dartium
# can figure out the tools directory because of the location of where the
# scripts blink scripts are located.
tools_dir = os.path.join(dart_dir, 'tools')
sys.path.insert(1, tools_dir)
sys.path.insert(1, third_party_dir)
sys.path.insert(1, os.path.join(dart_dir, 'tools/dom/scripts'))
import dartgenerator
import database
import fremontcutbuilder
import logging
import monitored
import multiemitter
import optparse
import shutil
import subprocess
import time
from dartmetadata import DartMetadata
from generator import TypeRegistry
from generate_blink_file import Generate_Blink
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, metadata,
dart_js_interop):
self.templates = templates
self.database = database
self.type_registry = type_registry
self.renamer = renamer
self.metadata = metadata
self.dart_js_interop = dart_js_interop
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,
update_dom_metadata=False,
logging_level=logging.WARNING,
dart_js_interop=False):
print('\n ----- Accessing DOM using %s -----\n' %
('dart:js' if dart_js_interop else 'C++'))
start_time = time.time()
current_dir = os.path.dirname(__file__)
auxiliary_dir = os.path.join(current_dir, '..', 'src')
template_dir = os.path.join(current_dir, '..', 'templates')
_logger.setLevel(logging_level)
generator = dartgenerator.DartGenerator(logging_level)
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)
generator.CleanupOperationArguments(webkit_database)
emitters = multiemitter.MultiEmitter(logging_level)
metadata = DartMetadata(
os.path.join(current_dir, '..', 'dom.json'),
os.path.join(current_dir, '..', 'docs', 'docs.json'), logging_level)
renamer = HtmlRenamer(webkit_database, metadata)
type_registry = TypeRegistry(webkit_database, renamer)
print('GenerateFromDatabase %s seconds' % round(
(time.time() - start_time), 2))
def RunGenerator(dart_libraries, dart_output_dir, template_loader,
backend_factory, dart_js_interop):
options = GeneratorOptions(template_loader, webkit_database,
type_registry, renamer, metadata,
dart_js_interop)
dart_library_emitter = DartLibraryEmitter(emitters, dart_output_dir,
dart_libraries)
event_generator = HtmlEventGenerator(webkit_database, renamer, metadata,
template_loader)
def generate_interface(interface, gl_constants=None):
backend = backend_factory(interface)
interface_generator = HtmlDartInterfaceGenerator(
options, dart_library_emitter, event_generator, interface,
backend)
interface_generator.Generate()
if len(backend._gl_constants) > 0 and not (gl_constants is None):
gl_constants.extend(backend._gl_constants)
generator.Generate(webkit_database, common_database, generate_interface)
dart_library_emitter.EmitLibraries(auxiliary_dir, dart_js_interop)
if dart2js_output_dir:
template_paths = ['html/dart2js', 'html/impl', 'html/interface', '']
template_loader = TemplateLoader(template_dir, template_paths, {
'DARTIUM': False,
'DART2JS': True,
'JSINTEROP': False,
'NNBD': True,
})
backend_options = GeneratorOptions(template_loader, webkit_database,
type_registry, renamer, metadata,
dart_js_interop)
backend_factory = lambda interface:\
Dart2JSBackend(interface, backend_options, logging_level)
dart_output_dir = os.path.join(dart2js_output_dir, 'dart')
dart_libraries = DartLibraries(HTML_LIBRARY_NAMES, template_loader,
'dart2js', dart2js_output_dir,
dart_js_interop)
for file in generator._auxiliary_files.values():
if file.endswith('darttemplate'):
dart_libraries._libraries['html'].AddFile(file)
print('\nGenerating dart2js:\n')
start_time = time.time()
RunGenerator(dart_libraries, dart_output_dir, template_loader,
backend_factory, dart_js_interop)
print('Generated dart2js in %s seconds' %
round(time.time() - start_time, 2))
emitters.Flush()
if update_dom_metadata:
metadata.Flush()
monitored.FinishMonitoring(dart2js_output_dir, _logger)
def GenerateSingleFile(library_path, output_dir, generated_output_dir=None, prefix=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)
if not os.path.exists(library_dir):
os.makedirs(library_dir)
prefix_arg = 'export DART_HTML_PREFIX="' + prefix + '";' if prefix else ""
command = ' '.join([
prefix_arg, 'cd', library_dir, ';', copy_dart_script, output_dir, library_filename
])
subprocess.call([command], shell=True)
dart_bin = os.path.join(utils.CheckedInSdkPath(), 'bin', 'dart')
sdk_file = os.path.join(library_dir, output_dir, library_filename)
formatCommand = ' '.join([dart_bin, 'format', sdk_file])
subprocess.call([formatCommand], shell=True)
def UpdateCssProperties():
"""Regenerate the CssStyleDeclaration template file with the current CSS
properties."""
_logger.info('Updating Css Properties.')
css_code_generator.GenerateCssTemplateFile()
CACHED_PATCHES = """
// START_OF_CACHED_PATCHES
// Copyright (c) 2013, 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.
// DO NOT EDIT GENERATED FILE.
library cached_patches;
var cached_patches = {
/********************************************************
***** *****
***** MUST RUN tools/dartium/generate_patches.sh *****
***** *****
********************************************************/
};
"""
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(
'--systems',
dest='systems',
action='store',
type='string',
default='htmldart2js,htmldartium,_blink',
help='Systems to generate (htmldart2js, htmldartium, _blink)')
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''')
parser.add_option(
'--update-dom-metadata',
dest='update_dom_metadata',
action='store_true',
default=False,
help='''Update the metadata list of DOM APIs''')
parser.add_option(
'--verbose',
dest='logging_level',
action='store_false',
default=logging.WARNING,
help='Output all informational messages')
parser.add_option(
'--examine',
dest='examine_idls',
action='store_true',
default=None,
help='Analyze IDL files')
parser.add_option(
'--logging',
dest='logging',
type='int',
action='store',
default=logging.NOTSET,
help='Level of logging 20 is Info, 30 is Warnings, 40 is Errors')
parser.add_option(
'--gen-interop',
dest='dart_js_interop',
action='store_true',
default=False,
help='Use Javascript objects (dart:js) accessing the DOM in _blink')
parser.add_option(
'--no-cached-patches',
dest='no_cached_patches',
action='store_true',
default=False,
help='Do not generate the sdk/lib/js/cached_patches.dart file')
(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()),
'generated')
dart2js_output_dir = None
if 'htmldart2js' in systems:
dart2js_output_dir = os.path.join(output_dir, 'dart2js')
logging_level = options.logging_level \
if options.logging == logging.NOTSET else options.logging
start_time = time.time()
UpdateCssProperties()
# Parse the IDL and create the database.
database = fremontcutbuilder.main(
options.parallel,
logging_level=logging_level,
examine_idls=options.examine_idls)
GenerateFromDatabase(database, dart2js_output_dir,
options.update_dom_metadata, logging_level,
options.dart_js_interop)
file_generation_start_time = time.time()
if 'htmldart2js' in systems:
_logger.info('Generating dart2js single files.')
for library_name in HTML_LIBRARY_NAMES:
source = os.path.join(dart2js_output_dir,
'%s_dart2js.dart' % library_name)
GenerateSingleFile(
source, os.path.join('..', '..', '..', 'sdk', 'lib',
library_name, 'dart2js'))
print('\nGenerating single file %s seconds' %
round(time.time() - file_generation_start_time, 2))
end_time = time.time()
print('\nDone (dartdomgenerator) %s seconds' %
round(end_time - start_time, 2))
if __name__ == '__main__':
sys.exit(main())