Commit 0a7d5573 authored by Yuki Shiino's avatar Yuki Shiino Committed by Commit Bot

bind-gen: Implement exposed interfaces and namespaces

Bug: 839389
Change-Id: Icb07d31a622bca16b70dea9e9a4e1ac5c83fb411
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1984791Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#728153}
parent 7b2ee5b3
......@@ -51,6 +51,7 @@ class CodeGenContext(object):
"constructor": None,
"constructor_group": None,
"dict_member": None,
"exposed_construct": None,
"operation": None,
"operation_group": None,
......@@ -224,7 +225,8 @@ class CodeGenContext(object):
@property
def property_(self):
return (self.attribute or self.constant or self.constructor_group
or self.dict_member or self.operation_group)
or self.dict_member or self.exposed_construct
or self.operation_group)
@property
def return_type(self):
......
......@@ -147,9 +147,9 @@ def expr_uniq(terms):
def expr_from_exposure(exposure, global_names=None):
"""
Args:
exposure: web_idl.Exposure
in_global: A global name of [Exposed] that the ExecutionContext is
supposed to be / represent.
exposure: web_idl.Exposure of the target construct.
global_names: When specified, it's taken into account that the global
object implements |global_names|.
"""
assert isinstance(exposure, web_idl.Exposure)
assert (global_names is None
......@@ -157,7 +157,9 @@ def expr_from_exposure(exposure, global_names=None):
and all(isinstance(name, str) for name in global_names)))
def ref_enabled(feature):
return _Expr("RuntimeEnabledFeatures::{}Enabled()".format(feature))
arg = "${execution_context}" if feature.is_context_dependent else ""
return _Expr("RuntimeEnabledFeatures::{}Enabled({})".format(
feature, arg))
top_terms = [_Expr(True)]
......@@ -175,15 +177,25 @@ def expr_from_exposure(exposure, global_names=None):
"Worklet": "IsWorkletGlobalScope",
}
exposed_terms = []
for entry in exposure.global_names_and_features:
terms = []
if entry.global_name not in (global_names or []):
if global_names is None:
for entry in exposure.global_names_and_features:
terms = []
pred = GLOBAL_NAME_TO_EXECUTION_CONTEXT_TEST[entry.global_name]
terms.append(_Expr("${{execution_context}}->{}()".format(pred)))
if entry.feature:
terms.append(ref_enabled(entry.feature))
if terms:
exposed_terms.append(expr_and(terms))
if entry.feature:
terms.append(ref_enabled(entry.feature))
if terms:
exposed_terms.append(expr_and(terms))
else:
matched_global_count = 0
for entry in exposure.global_names_and_features:
if entry.global_name not in global_names:
continue
matched_global_count += 1
if entry.feature:
exposed_terms.append(ref_enabled(entry.feature))
assert (not exposure.global_names_and_features
or matched_global_count > 0)
if exposed_terms:
top_terms.append(expr_or(exposed_terms))
......
......@@ -5,13 +5,29 @@
from .runtime_enabled_features import RuntimeEnabledFeatures
class _Feature(str):
"""Represents a runtime-enabled feature."""
def __init__(self, value):
str.__init__(self, value)
self._is_context_dependent = (
RuntimeEnabledFeatures.is_context_dependent(self))
@property
def is_context_dependent(self):
return self._is_context_dependent
class _GlobalNameAndFeature(object):
def __init__(self, global_name, feature=None):
assert isinstance(global_name, str)
assert feature is None or isinstance(feature, str)
self._global_name = global_name
self._feature = feature
if feature is None:
self._feature = None
else:
self._feature = _Feature(feature)
@property
def global_name(self):
......@@ -23,6 +39,8 @@ class _GlobalNameAndFeature(object):
class Exposure(object):
"""Represents a set of conditions under which the construct is exposed."""
def __init__(self, other=None):
assert other is None or isinstance(other, Exposure)
......@@ -94,15 +112,33 @@ class Exposure(object):
return False
return self._only_in_secure_contexts
@property
def is_context_dependent(self):
def is_context_dependent(self, global_names=None):
"""
Returns True if the exposure of this construct depends on a context.
Args:
global_names: When specified, it's taken into account that the
global object implements |global_names|.
"""
return bool(self.global_names_and_features
or self.context_dependent_runtime_enabled_features
or self.context_enabled_features
or self.only_in_secure_contexts)
assert (global_names is None
or (isinstance(global_names, (list, tuple))
and all(isinstance(name, str) for name in global_names)))
if (self.context_dependent_runtime_enabled_features
or self.context_enabled_features
or self.only_in_secure_contexts):
return True
if not global_names:
return bool(self.global_names_and_features)
is_context_dependent = False
for entry in self.global_names_and_features:
if entry.global_name not in global_names:
continue
if entry.feature and entry.feature.is_context_dependent:
is_context_dependent = True
return is_context_dependent
class ExposureMutable(Exposure):
......@@ -128,11 +164,12 @@ class ExposureMutable(Exposure):
def add_runtime_enabled_feature(self, name):
assert isinstance(name, str)
if RuntimeEnabledFeatures.is_context_dependent(name):
self._context_dependent_runtime_enabled_features.append(name)
feature = _Feature(name)
if feature.is_context_dependent:
self._context_dependent_runtime_enabled_features.append(feature)
else:
self._context_independent_runtime_enabled_features.append(name)
self._runtime_enabled_features.append(name)
self._context_independent_runtime_enabled_features.append(feature)
self._runtime_enabled_features.append(feature)
def add_context_enabled_feature(self, name):
assert isinstance(name, str)
......@@ -146,6 +183,6 @@ class ExposureMutable(Exposure):
if isinstance(value, bool):
self._only_in_secure_contexts = value
elif isinstance(value, str):
self._only_in_secure_contexts = (value, )
self._only_in_secure_contexts = (_Feature(value), )
else:
self._only_in_secure_contexts = tuple(value)
self._only_in_secure_contexts = tuple(map(_Feature, value))
......@@ -280,5 +280,11 @@ class ExtendedAttributes(object):
class ExtendedAttributesMutable(ExtendedAttributes):
def __getstate__(self):
assert False, "ExtendedAttributesMutable must not be pickled."
def __setstate__(self, state):
assert False, "ExtendedAttributesMutable must not be pickled."
def append(self, ext_attr):
self._append(ext_attr)
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