Files
sdk/tools/dom/scripts/dartdomgenerator.py
T
Srujan Gaddam e872b7addd [web libraries] Capture annotations and header comments when expanding parts
copy_dart.py parses the generated web libraries to split them
into components so that it can expand part declarations. This
script should recognize any annotations and header comments
(like the license) so that it can accurately copy them over.

Ideally, we shouldn't be parsing anything besides the part
declarations and expanding them as we just attempt to copy
anything else, but that can be done in a future change.

Note that this change adds @deprecated back to the library
declaration in web_sql_dart2js.dart. It makes no difference,
however, as it's a compile time error to import dart:web_sql
anyways.

CoreLibraryReviewExempt: Doc-only change.
Change-Id: Iad974434b858ea36358f908e8a25987105c586c7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/401801
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
2024-12-19 13:26:20 -08:00

388 lines
14 KiB
Python
Executable File

#!/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())