| #!/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 WebCore is 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. | |
| sys.path.insert(1, os.path.join(dart_dir, 'third_party/WebCore')) | |
| 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 prototype_htmleventgenerator import Prototype_HtmlEventGenerator | |
| 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, | |
| generate_static_extensions=False, | |
| generate_prototype_events=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.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) | |
| prototype_event_generator = Prototype_HtmlEventGenerator( | |
| webkit_database, renamer, metadata, event_generator) | |
| def generate_interface(interface, gl_constants=None): | |
| backend = backend_factory(interface) | |
| interface_generator = HtmlDartInterfaceGenerator( | |
| options, dart_library_emitter, event_generator, | |
| prototype_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) | |
| if generate_prototype_events: | |
| dart_bin = os.path.join(utils.CheckedInSdkPath(), 'bin', 'dart') | |
| prototype_event_generator.WriteFile(dart_bin) | |
| 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, generate_static_extensions) | |
| 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) | |
| # Expand part files and concatenate them. | |
| 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') | |
| parser.add_option( | |
| '--generate-static-extensions', | |
| dest='generate_static_extensions', | |
| action='store_true', | |
| default=False, | |
| help='Generate static extension members for dart:html classes') | |
| parser.add_option( | |
| '--generate-prototype-events', | |
| dest='generate_prototype_events', | |
| action='store_true', | |
| default=False, | |
| help='Generate event stream library for dart:html prototype') | |
| (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, | |
| options.generate_static_extensions, | |
| options.generate_prototype_events) | |
| 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()) |