blob: bd5fcad6ec29014a812c358cfff8bd7dbd11304c [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.
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())