#!/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) prebuilt_dartfmt = os.path.join(utils.CheckedInSdkPath(), 'bin', 'dartfmt') sdk_file = os.path.join(library_dir, output_dir, library_filename) formatCommand = ' '.join([prebuilt_dartfmt, '-w', 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())