Commit cbade2a9 authored by Yuki Shiino's avatar Yuki Shiino Committed by Commit Bot

IDL compiler: Support context-{in,}dependence of runtime-enabled features

Makes the IDL compiler processes runtime_enabled_features.json5
and makes Exposure aware of context-dependent and context-
independent runtime enabled features.

Bug: 839389
Change-Id: I2d46730f22866f6f677a96dbd7a72644253e4692
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1892973
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#711998}
parent 5bb53947
...@@ -88,7 +88,7 @@ collect_idl_files("web_idl_in_core") { ...@@ -88,7 +88,7 @@ collect_idl_files("web_idl_in_core") {
inputs += [ "${bindings_scripts_dir}/web_idl/migration_adapter.idl" ] inputs += [ "${bindings_scripts_dir}/web_idl/migration_adapter.idl" ]
# Additional IDL files to test and demonstrate the new IDL compiler. # Additional IDL files to test and demonstrate the new IDL compiler.
inputs += [ "${bindings_scripts_dir}/web_idl/idl_compiler_test.idl" ] inputs += [ "${bindings_scripts_dir}/web_idl/demonstration_and_testing.idl" ]
component = "core" component = "core"
output = "${bindings_output_dir}/web_idl_in_core.pickle" output = "${bindings_output_dir}/web_idl_in_core.pickle"
...@@ -111,7 +111,13 @@ action_with_pydeps("web_idl_database") { ...@@ -111,7 +111,13 @@ action_with_pydeps("web_idl_database") {
input_data_files = get_target_outputs(":web_idl_in_core") + input_data_files = get_target_outputs(":web_idl_in_core") +
get_target_outputs(":web_idl_in_modules") get_target_outputs(":web_idl_in_modules")
inputs = input_data_files runtime_enabled_features_file = "../platform/runtime_enabled_features.json5"
runtime_enabled_features_test_file =
"${bindings_scripts_dir}/web_idl/runtime_enabled_features.json5"
inputs = input_data_files + [
runtime_enabled_features_file,
runtime_enabled_features_test_file,
]
output_data_file = "${bindings_output_dir}/web_idl_database.pickle" output_data_file = "${bindings_output_dir}/web_idl_database.pickle"
outputs = [ outputs = [
output_data_file, output_data_file,
...@@ -120,6 +126,10 @@ action_with_pydeps("web_idl_database") { ...@@ -120,6 +126,10 @@ action_with_pydeps("web_idl_database") {
args = [ args = [
"--output", "--output",
rebase_path(output_data_file, root_build_dir), rebase_path(output_data_file, root_build_dir),
"--runtime_enabled_features",
rebase_path(runtime_enabled_features_file, root_build_dir),
"--runtime_enabled_features",
rebase_path(runtime_enabled_features_test_file, root_build_dir),
"--", "--",
] + rebase_path(input_data_files, root_build_dir) ] + rebase_path(input_data_files, root_build_dir)
......
...@@ -19,10 +19,15 @@ def parse_options(): ...@@ -19,10 +19,15 @@ def parse_options():
parser = optparse.OptionParser() parser = optparse.OptionParser()
parser.add_option('--output', type='string', parser.add_option('--output', type='string',
help="filepath of the resulting database") help="filepath of the resulting database")
parser.add_option('--runtime_enabled_features', type='string',
action='append',
help="filepath to runtime_enabled_features.json5")
options, args = parser.parse_args() options, args = parser.parse_args()
if options.output is None: required_option_names = ('output', 'runtime_enabled_features')
parser.error("Specify a filepath of the database with --output.") for opt_name in required_option_names:
if getattr(options, opt_name) is None:
parser.error("--{} is a required option.".format(opt_name))
if not args: if not args:
parser.error("No argument specified.") parser.error("No argument specified.")
...@@ -33,6 +38,9 @@ def parse_options(): ...@@ -33,6 +38,9 @@ def parse_options():
def main(): def main():
options, filepaths = parse_options() options, filepaths = parse_options()
web_idl.init(
runtime_enabled_features_paths=options.runtime_enabled_features)
was_error_reported = [False] was_error_reported = [False]
def report_error(message): def report_error(message):
......
# Generated by running: # Generated by running:
# build/print_python_deps.py --root third_party/blink/renderer/bindings/scripts --output third_party/blink/renderer/bindings/scripts/build_web_idl_database.pydeps third_party/blink/renderer/bindings/scripts/build_web_idl_database.py # build/print_python_deps.py --root third_party/blink/renderer/bindings/scripts --output third_party/blink/renderer/bindings/scripts/build_web_idl_database.pydeps third_party/blink/renderer/bindings/scripts/build_web_idl_database.py
../../../../pyjson5/src/json5/__init__.py
../../../../pyjson5/src/json5/arg_parser.py
../../../../pyjson5/src/json5/host.py
../../../../pyjson5/src/json5/lib.py
../../../../pyjson5/src/json5/parser.py
../../../../pyjson5/src/json5/tool.py
../../../../pyjson5/src/json5/version.py
../../build/scripts/blinkbuild/__init__.py ../../build/scripts/blinkbuild/__init__.py
../../build/scripts/blinkbuild/name_style_converter.py ../../build/scripts/blinkbuild/name_style_converter.py
build_web_idl_database.py build_web_idl_database.py
...@@ -33,6 +40,7 @@ web_idl/namespace.py ...@@ -33,6 +40,7 @@ web_idl/namespace.py
web_idl/operation.py web_idl/operation.py
web_idl/overload_group.py web_idl/overload_group.py
web_idl/reference.py web_idl/reference.py
web_idl/runtime_enabled_features.py
web_idl/typedef.py web_idl/typedef.py
web_idl/union.py web_idl/union.py
web_idl/user_defined_type.py web_idl/user_defined_type.py
...@@ -7,6 +7,13 @@ ...@@ -7,6 +7,13 @@
../../../../ply/__init__.py ../../../../ply/__init__.py
../../../../ply/lex.py ../../../../ply/lex.py
../../../../ply/yacc.py ../../../../ply/yacc.py
../../../../pyjson5/src/json5/__init__.py
../../../../pyjson5/src/json5/arg_parser.py
../../../../pyjson5/src/json5/host.py
../../../../pyjson5/src/json5/lib.py
../../../../pyjson5/src/json5/parser.py
../../../../pyjson5/src/json5/tool.py
../../../../pyjson5/src/json5/version.py
../../build/scripts/blinkbuild/__init__.py ../../build/scripts/blinkbuild/__init__.py
../../build/scripts/blinkbuild/name_style_converter.py ../../build/scripts/blinkbuild/name_style_converter.py
blink_idl_lexer.py blink_idl_lexer.py
...@@ -43,6 +50,7 @@ web_idl/namespace.py ...@@ -43,6 +50,7 @@ web_idl/namespace.py
web_idl/operation.py web_idl/operation.py
web_idl/overload_group.py web_idl/overload_group.py
web_idl/reference.py web_idl/reference.py
web_idl/runtime_enabled_features.py
web_idl/typedef.py web_idl/typedef.py
web_idl/union.py web_idl/union.py
web_idl/user_defined_type.py web_idl/user_defined_type.py
...@@ -17,6 +17,13 @@ ...@@ -17,6 +17,13 @@
../../../../mako/mako/runtime.py ../../../../mako/mako/runtime.py
../../../../mako/mako/template.py ../../../../mako/mako/template.py
../../../../mako/mako/util.py ../../../../mako/mako/util.py
../../../../pyjson5/src/json5/__init__.py
../../../../pyjson5/src/json5/arg_parser.py
../../../../pyjson5/src/json5/host.py
../../../../pyjson5/src/json5/lib.py
../../../../pyjson5/src/json5/parser.py
../../../../pyjson5/src/json5/tool.py
../../../../pyjson5/src/json5/version.py
../../build/scripts/blinkbuild/__init__.py ../../build/scripts/blinkbuild/__init__.py
../../build/scripts/blinkbuild/name_style_converter.py ../../build/scripts/blinkbuild/name_style_converter.py
bind_gen/__init__.py bind_gen/__init__.py
...@@ -56,6 +63,7 @@ web_idl/namespace.py ...@@ -56,6 +63,7 @@ web_idl/namespace.py
web_idl/operation.py web_idl/operation.py
web_idl/overload_group.py web_idl/overload_group.py
web_idl/reference.py web_idl/reference.py
web_idl/runtime_enabled_features.py
web_idl/typedef.py web_idl/typedef.py
web_idl/union.py web_idl/union.py
web_idl/user_defined_type.py web_idl/user_defined_type.py
...@@ -19,6 +19,8 @@ def _setup_sys_path(): ...@@ -19,6 +19,8 @@ def _setup_sys_path():
'scripts'), 'scripts'),
# //third_party/ply # //third_party/ply
os.path.join(root_dir, 'third_party'), os.path.join(root_dir, 'third_party'),
# //third_party/pyjson5/src/json5
os.path.join(root_dir, 'third_party', 'pyjson5', 'src'),
# //tools/idl_parser # //tools/idl_parser
os.path.join(root_dir, 'tools'), os.path.join(root_dir, 'tools'),
] + sys.path ] + sys.path
...@@ -31,6 +33,16 @@ from .ast_group import AstGroup ...@@ -31,6 +33,16 @@ from .ast_group import AstGroup
from .composition_parts import Component from .composition_parts import Component
from .database import Database from .database import Database
from .database_builder import build_database from .database_builder import build_database
from .runtime_enabled_features import RuntimeEnabledFeatures
def init(runtime_enabled_features_paths):
"""
Args:
runtime_enabled_features_paths: Paths to the definition files of
runtime-enabled features ("runtime_enabled_features.json5").
"""
RuntimeEnabledFeatures.init(filepaths=runtime_enabled_features_paths)
__all__ = [ __all__ = [
......
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
from .ir_map import IRMap
from .idl_compiler import IdlCompiler from .idl_compiler import IdlCompiler
from .idl_type import IdlTypeFactory from .idl_type import IdlTypeFactory
from .ir_builder import load_and_register_idl_definitions from .ir_builder import load_and_register_idl_definitions
from .ir_map import IRMap
from .reference import RefByIdFactory from .reference import RefByIdFactory
...@@ -20,17 +20,22 @@ def build_database(filepaths, report_error): ...@@ -20,17 +20,22 @@ def build_database(filepaths, report_error):
error message of type str and return value is not used. It's okay error message of type str and return value is not used. It's okay
to terminate the program in this callback. to terminate the program in this callback.
""" """
assert isinstance(filepaths, (list, tuple))
assert all(isinstance(filepath, str) for filepath in filepaths)
assert callable(report_error)
ir_map = IRMap() ir_map = IRMap()
ref_to_idl_type_factory = RefByIdFactory() ref_to_idl_type_factory = RefByIdFactory()
ref_to_idl_def_factory = RefByIdFactory() ref_to_idl_def_factory = RefByIdFactory()
idl_type_factory = IdlTypeFactory() idl_type_factory = IdlTypeFactory()
load_and_register_idl_definitions( load_and_register_idl_definitions(
filepaths=filepaths, filepaths=filepaths,
register_ir=ir_map.register, register_ir=ir_map.register,
create_ref_to_idl_def=ref_to_idl_def_factory.create, create_ref_to_idl_def=ref_to_idl_def_factory.create,
create_ref_to_idl_type=ref_to_idl_type_factory.create, create_ref_to_idl_type=ref_to_idl_type_factory.create,
idl_type_factory=idl_type_factory) idl_type_factory=idl_type_factory)
compiler = IdlCompiler( compiler = IdlCompiler(
ir_map=ir_map, ir_map=ir_map,
ref_to_idl_def_factory=ref_to_idl_def_factory, ref_to_idl_def_factory=ref_to_idl_def_factory,
......
...@@ -2,13 +2,19 @@ ...@@ -2,13 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// This file is used only during the development of the new bindings generator
// (especially until we'll have a good test suite) and pretty much temporary.
// The IDL definitions in this file are used for half testing purpose and for
// half demonstration purpose of the new bindings generator.
[ [
Exposed=Window Exposed=Window
] interface TestInterfaceConstructor { ] interface TestInterfaceConstructor {
constructor(); constructor();
constructor(DOMString arg1); constructor(DOMString arg1);
[Custom] constructor(Node node); [Custom] constructor(Node node);
[RuntimeEnabled=Hoge] constructor(long num); [RuntimeEnabled=TestFeature1] constructor(long num);
}; };
namespace TestNamespace { namespace TestNamespace {
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
from .runtime_enabled_features import RuntimeEnabledFeatures
class _GlobalNameAndFeature(object): class _GlobalNameAndFeature(object):
def __init__(self, global_name, feature=None): def __init__(self, global_name, feature=None):
...@@ -29,12 +31,18 @@ class Exposure(object): ...@@ -29,12 +31,18 @@ class Exposure(object):
other.global_names_and_features) other.global_names_and_features)
self._runtime_enabled_features = tuple( self._runtime_enabled_features = tuple(
other.runtime_enabled_features) other.runtime_enabled_features)
self._context_independent_runtime_enabled_features = tuple(
other.context_independent_runtime_enabled_features)
self._context_dependent_runtime_enabled_features = tuple(
other.context_dependent_runtime_enabled_features)
self._context_enabled_features = tuple( self._context_enabled_features = tuple(
other.context_enabled_features) other.context_enabled_features)
self._only_in_secure_contexts = other.only_in_secure_contexts self._only_in_secure_contexts = other.only_in_secure_contexts
else: else:
self._global_names_and_features = tuple() self._global_names_and_features = tuple()
self._runtime_enabled_features = tuple() self._runtime_enabled_features = tuple()
self._context_independent_runtime_enabled_features = tuple()
self._context_dependent_runtime_enabled_features = tuple()
self._context_enabled_features = tuple() self._context_enabled_features = tuple()
self._only_in_secure_contexts = None self._only_in_secure_contexts = None
...@@ -54,6 +62,16 @@ class Exposure(object): ...@@ -54,6 +62,16 @@ class Exposure(object):
""" """
return self._runtime_enabled_features return self._runtime_enabled_features
@property
def context_independent_runtime_enabled_features(self):
"""Returns runtime enabled features that are context-independent."""
return self._context_independent_runtime_enabled_features
@property
def context_dependent_runtime_enabled_features(self):
"""Returns runtime enabled features that are context-dependent."""
return self._context_dependent_runtime_enabled_features
@property @property
def context_enabled_features(self): def context_enabled_features(self):
""" """
...@@ -83,6 +101,8 @@ class ExposureMutable(Exposure): ...@@ -83,6 +101,8 @@ class ExposureMutable(Exposure):
self._global_names_and_features = [] self._global_names_and_features = []
self._runtime_enabled_features = [] self._runtime_enabled_features = []
self._context_independent_runtime_enabled_features = []
self._context_dependent_runtime_enabled_features = []
self._context_enabled_features = [] self._context_enabled_features = []
self._only_in_secure_contexts = None self._only_in_secure_contexts = None
...@@ -98,6 +118,10 @@ class ExposureMutable(Exposure): ...@@ -98,6 +118,10 @@ class ExposureMutable(Exposure):
def add_runtime_enabled_feature(self, name): def add_runtime_enabled_feature(self, name):
assert isinstance(name, str) assert isinstance(name, str)
if RuntimeEnabledFeatures.is_context_dependent(name):
self._context_dependent_runtime_enabled_features.append(name)
else:
self._context_independent_runtime_enabled_features.append(name)
self._runtime_enabled_features.append(name) self._runtime_enabled_features.append(name)
def add_context_enabled_feature(self, name): def add_context_enabled_feature(self, name):
......
...@@ -13,9 +13,9 @@ from .database import Database ...@@ -13,9 +13,9 @@ from .database import Database
from .database import DatabaseBody from .database import DatabaseBody
from .dictionary import Dictionary from .dictionary import Dictionary
from .enumeration import Enumeration from .enumeration import Enumeration
from .ir_map import IRMap
from .idl_type import IdlTypeFactory from .idl_type import IdlTypeFactory
from .interface import Interface from .interface import Interface
from .ir_map import IRMap
from .make_copy import make_copy from .make_copy import make_copy
from .namespace import Namespace from .namespace import Namespace
from .operation import OperationGroup from .operation import OperationGroup
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file is used only for testing purposes, and is never used for
// production. For production purposes, see the following file:
// //third_party/blink/renderer/platform/runtime_enabled_features.json5
//
// This file is used to add runtime enabled features in order to test the Web
// IDL compiler and bindings code generator.
{
data: [
{
name: "TestFeature1",
},
{
name: "TestFeature2",
origin_trial_feature_name: "TestFeature2",
},
]
}
# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import json5
class RuntimeEnabledFeatures(object):
"""Represents a set of definitions of runtime enabled features."""
_REQUIRE_INIT_MESSAGE = (
"RuntimeEnabledFeatures.init must be called in advance.")
@classmethod
def init(cls, filepaths):
"""
Args:
filepaths: Paths to the definition files of runtime-enabled features
("runtime_enabled_features.json5").
"""
assert isinstance(filepaths, list)
assert all(isinstance(filepath, str) for filepath in filepaths)
cls._features = {}
for filepath in filepaths:
with open(filepath) as file_obj:
datastore = json5.load(file_obj)
for entry in datastore["data"]:
assert entry["name"] not in cls._features
cls._features[entry["name"]] = entry
cls._is_initialized = True
@classmethod
def is_context_dependent(cls, feature_name):
"""Returns True if the feature may be enabled per-context."""
assert cls._is_initialized, _REQUIRE_INIT_MESSAGE
assert isinstance(feature_name, str)
assert feature_name in cls._features, (
"Unknown runtime-enabled feature: {}".format(feature_name))
return cls._features[feature_name].get(
"origin_trial_feature_name") is not None
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment