| #!/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. |
| |
| import database |
| import databasebuilder |
| import idlnode |
| import logging.config |
| import os.path |
| import sys |
| import time |
| import utilities |
| import dependency |
| from idlnode import IDLType, resolveTypedef |
| |
| _logger = logging.getLogger('fremontcutbuilder') |
| |
| # See: |
| # http://src.chromium.org/viewvc/multivm/trunk/webkit/Source/core/features.gypi |
| # for ENABLE_* flags defined in Chromium / Blink. |
| # We list all ENABLE flags used in IDL in one of these two lists. |
| FEATURE_DISABLED = [ |
| 'ENABLE_CUSTOM_SCHEME_HANDLER', |
| 'ENABLE_MEDIA_CAPTURE', # Only enabled on Android. |
| 'ENABLE_ORIENTATION_EVENTS', # Only enabled on Android. |
| 'ENABLE_WEBVTT_REGIONS', |
| ] |
| |
| FEATURE_DEFINES = [ |
| 'ENABLE_CALENDAR_PICKER', # Not on Android |
| 'ENABLE_ENCRYPTED_MEDIA_V2', |
| 'ENABLE_INPUT_SPEECH', # Not on Android |
| 'ENABLE_LEGACY_NOTIFICATIONS', # Not on Android |
| 'ENABLE_NAVIGATOR_CONTENT_UTILS', # Not on Android |
| 'ENABLE_NOTIFICATIONS', # Not on Android |
| 'ENABLE_SVG_FONTS', |
| 'ENABLE_WEB_AUDIO', # Not on Android |
| ] |
| |
| |
| # Resolve all typedefs encountered while parsing (see idlnode.py), resolve any typedefs not resolved |
| # during parsing. This must be done before the database is created, merged, and augmented to |
| # exact type matching. Typedefs can be encountered in any IDL and usage can cross IDL boundaries. |
| def ResolveAllTypedefs(all_interfaces): |
| # Resolve all typedefs. |
| for interface, db_Opts in all_interfaces: |
| |
| def IsIdentified(idl_node): |
| node_name = idl_node.id if idl_node.id else 'parent' |
| for idl_type in idl_node.all(idlnode.IDLType): |
| # One last check is the type a typedef in an IDL file (the typedefs |
| # are treated as global). |
| resolvedType = resolveTypedef(idl_type) |
| if (resolvedType != idl_type): |
| idl_type.id = resolvedType.id |
| idl_type.nullable = resolvedType.nullable |
| continue |
| return True |
| |
| interface.constants = filter(IsIdentified, interface.constants) |
| interface.attributes = filter(IsIdentified, interface.attributes) |
| interface.operations = filter(IsIdentified, interface.operations) |
| interface.parents = filter(IsIdentified, interface.parents) |
| |
| |
| def build_database(idl_files, |
| database_dir, |
| feature_defines=None, |
| logging_level=logging.WARNING, |
| examine_idls=False): |
| """This code reconstructs the FremontCut IDL database from W3C, |
| WebKit and Dart IDL files.""" |
| current_dir = os.path.dirname(__file__) |
| logging.config.fileConfig(os.path.join(current_dir, "logging.conf")) |
| |
| _logger.setLevel(logging_level) |
| |
| db = database.Database(database_dir) |
| |
| # Delete all existing IDLs in the DB. |
| db.Delete() |
| |
| builder = databasebuilder.DatabaseBuilder(db) |
| dependency.set_builder(builder) |
| |
| # TODO(vsm): Move this to a README. |
| # This is the Chrome revision. |
| webkit_revision = '63' |
| |
| # TODO(vsm): Reconcile what is exposed here and inside WebKit code |
| # generation. We need to recheck this periodically for now. |
| webkit_defines = ['LANGUAGE_DART', 'LANGUAGE_JAVASCRIPT'] |
| |
| if feature_defines is None: |
| feature_defines = FEATURE_DEFINES |
| |
| webkit_options = databasebuilder.DatabaseBuilderOptions( |
| # TODO(vsm): What else should we define as on when processing IDL? |
| idl_defines=webkit_defines + feature_defines, |
| source='WebKit', |
| source_attributes={'revision': webkit_revision}, |
| logging_level=logging_level) |
| |
| # Import WebKit IDLs. |
| builder.import_idl_files(idl_files, webkit_options, False) |
| |
| # Import Dart idl: |
| dart_options = databasebuilder.DatabaseBuilderOptions( |
| source='Dart', |
| rename_operation_arguments_on_merge=True, |
| logging_level=logging_level) |
| |
| utilities.KNOWN_COMPONENTS = frozenset(['core', 'modules', 'dart']) |
| |
| builder.import_idl_files( |
| [os.path.join(current_dir, '..', 'idl', 'dart', 'dart.idl')], |
| dart_options, True) |
| |
| start_time = time.time() |
| |
| # All typedefs MUST be resolved here before any database fixups (merging, implements, etc.) |
| ResolveAllTypedefs(builder._imported_interfaces) |
| |
| # Merging: |
| builder.merge_imported_interfaces() |
| |
| builder.fetch_constructor_data(webkit_options) |
| builder.fix_displacements('WebKit') |
| |
| # Cleanup: |
| builder.normalize_annotations(['WebKit', 'Dart']) |
| |
| # Map any IDL defined dictionaries to Dictionary. |
| builder.map_dictionaries() |
| |
| # Examine all IDL and produce a diagnoses of areas (e.g., list dictionaries |
| # declared and usage, etc.) |
| if examine_idls: |
| builder.examine_database() |
| |
| conditionals_met = set( |
| 'ENABLE_' + conditional for conditional in builder.conditionals_met) |
| known_conditionals = set(FEATURE_DEFINES + FEATURE_DISABLED) |
| |
| unused_conditionals = known_conditionals - conditionals_met |
| if unused_conditionals: |
| _logger.warning('There are some unused conditionals %s' % |
| sorted(unused_conditionals)) |
| _logger.warning('Please update fremontcutbuilder.py') |
| |
| unknown_conditionals = conditionals_met - known_conditionals |
| if unknown_conditionals: |
| _logger.warning('There are some unknown conditionals %s' % |
| sorted(unknown_conditionals)) |
| _logger.warning('Please update fremontcutbuilder.py') |
| |
| print('Merging interfaces %s seconds' % round(time.time() - start_time, 2)) |
| |
| return db |
| |
| |
| def main(parallel=False, logging_level=logging.WARNING, examine_idls=False): |
| current_dir = os.path.dirname(__file__) |
| |
| idl_files = [] |
| |
| # Check default location in a regular dart enlistment. |
| webcore_dir = os.path.join(current_dir, '..', '..', '..', 'third_party', |
| 'WebCore') |
| |
| if not os.path.exists(webcore_dir): |
| # Check default location in a dartium enlistment. |
| webcore_dir = os.path.join(current_dir, '..', '..', '..', '..', |
| 'third_party', 'WebKit', 'Source') |
| |
| if not os.path.exists(webcore_dir): |
| raise RuntimeError('directory not found: %s' % webcore_dir) |
| |
| DIRS_TO_IGNORE = [ |
| 'bindings', # Various test IDLs |
| 'testing', # IDLs to expose testing APIs |
| 'networkinfo', # Not yet used in Blink yet |
| 'vibration', # Not yet used in Blink yet |
| 'inspector', |
| ] |
| |
| # TODO(terry): Integrate this into the htmlrenamer's _removed_html_interfaces |
| # (if possible). |
| FILES_TO_IGNORE = [ |
| 'InspectorFrontendHostFileSystem.idl', # Uses interfaces in inspector dir (which is ignored) |
| 'WebKitGamepad.idl', # Gamepad.idl is the new one. |
| 'WebKitGamepadList.idl', # GamepadList is the new one. |
| ] |
| |
| def visitor(arg, dir_name, names): |
| if os.path.basename(dir_name) in DIRS_TO_IGNORE: |
| names[:] = [] # Do not go underneath |
| for name in names: |
| file_name = os.path.join(dir_name, name) |
| (interface, ext) = os.path.splitext(file_name) |
| if ext == '.idl' and not (name in FILES_TO_IGNORE): |
| idl_files.append(file_name) |
| |
| os.path.walk(webcore_dir, visitor, webcore_dir) |
| |
| database_dir = os.path.join(current_dir, '..', 'database') |
| |
| return build_database( |
| idl_files, |
| database_dir, |
| logging_level=logging_level, |
| examine_idls=examine_idls) |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main()) |