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

IDL compiler: Calculate overloaded group's exposure

Bug: 839389
Change-Id: I2094369240b2174bf2cc874a79bec1f4222bc3d8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1893113Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#711641}
parent bfbb36ea
......@@ -36,7 +36,7 @@ class Exposure(object):
self._global_names_and_features = tuple()
self._runtime_enabled_features = tuple()
self._context_enabled_features = tuple()
self._only_in_secure_contexts = False
self._only_in_secure_contexts = None
@property
def global_names_and_features(self):
......@@ -50,7 +50,7 @@ class Exposure(object):
def runtime_enabled_features(self):
"""
Returns a list of runtime enabled features. This construct is exposed
only when these features are enabled.
only when one of these features is enabled.
"""
return self._runtime_enabled_features
......@@ -58,7 +58,7 @@ class Exposure(object):
def context_enabled_features(self):
"""
Returns a list of context enabled features. This construct is exposed
only when these features are enabled in the context.
only when one of these features is enabled in the context.
"""
return self._context_enabled_features
......@@ -66,11 +66,14 @@ class Exposure(object):
def only_in_secure_contexts(self):
"""
Returns whether this construct is available only in secure contexts or
not. The returned value will be either of a boolean (always true or
false) or a flag name (only when the flag is enabled).
not. The returned value is either of a boolean (True: unconditionally
restricted in secure contexts, or False: never restricted) or a list of
flag names (restricted only when all flags are enabled).
https://heycam.github.io/webidl/#dfn-available-only-in-secure-contexts
"""
if self._only_in_secure_contexts is None:
return False
return self._only_in_secure_contexts
......@@ -81,7 +84,7 @@ class ExposureMutable(Exposure):
self._global_names_and_features = []
self._runtime_enabled_features = []
self._context_enabled_features = []
self._only_in_secure_contexts = False
self._only_in_secure_contexts = None
def __getstate__(self):
assert False, "ExposureMutable must not be pickled."
......@@ -102,6 +105,13 @@ class ExposureMutable(Exposure):
self._context_enabled_features.append(name)
def set_only_in_secure_contexts(self, value):
assert isinstance(value, (bool, str))
assert self._only_in_secure_contexts is False and value is not False
self._only_in_secure_contexts = value
assert (isinstance(value, (bool, str))
or (isinstance(value, (list, tuple))
and all(isinstance(name, str) for name in value)))
assert self._only_in_secure_contexts is None
if isinstance(value, bool):
self._only_in_secure_contexts = value
elif isinstance(value, str):
self._only_in_secure_contexts = (value, )
else:
self._only_in_secure_contexts = tuple(value)
......@@ -91,6 +91,7 @@ class IdlCompiler(object):
# Make groups of overloaded functions including inherited ones.
self._group_overloaded_functions()
self._calculate_group_exposure()
# Updates on IRs are finished. Create API objects.
self._create_public_objects()
......@@ -150,6 +151,7 @@ class IdlCompiler(object):
def process_interface_like(ir):
ir = make_copy(ir)
self._ir_map.add(ir)
propagate = functools.partial(propagate_extattr, ir=ir)
propagate(('ImplementedAs', 'set_receiver_implemented_as'),
......@@ -159,8 +161,6 @@ class IdlCompiler(object):
map(process_member_like, ir.iter_all_members())
self._ir_map.add(ir)
def process_member_like(ir):
propagate = functools.partial(propagate_extattr, ir=ir)
propagate(('ImplementedAs', 'set_property_implemented_as'),
......@@ -211,6 +211,7 @@ class IdlCompiler(object):
for identifier, old_dictionary in old_dictionaries.iteritems():
new_dictionary = make_copy(old_dictionary)
self._ir_map.add(new_dictionary)
for partial_dictionary in old_partial_dictionaries.get(
identifier, []):
new_dictionary.add_components(partial_dictionary.components)
......@@ -218,7 +219,6 @@ class IdlCompiler(object):
partial_dictionary.debug_info.all_locations)
new_dictionary.own_members.extend(
make_copy(partial_dictionary.own_members))
self._ir_map.add(new_dictionary)
def _merge_interface_mixins(self):
interfaces = self._ir_map.find_by_kind(IRMap.IR.Kind.INTERFACE)
......@@ -237,6 +237,7 @@ class IdlCompiler(object):
def _merge_interface_like_irs(self, old_irs_to_merge):
for old_ir, irs_to_be_merged in old_irs_to_merge:
new_ir = make_copy(old_ir)
self._ir_map.add(new_ir)
for ir in irs_to_be_merged:
to_be_merged = make_copy(ir)
new_ir.add_components(to_be_merged.components)
......@@ -245,7 +246,6 @@ class IdlCompiler(object):
new_ir.attributes.extend(to_be_merged.attributes)
new_ir.constants.extend(to_be_merged.constants)
new_ir.operations.extend(to_be_merged.operations)
self._ir_map.add(new_ir)
def _process_interface_inheritances(self):
def is_own_member(member):
......@@ -263,6 +263,7 @@ class IdlCompiler(object):
for old_interface in old_interfaces.itervalues():
new_interface = make_copy(old_interface)
self._ir_map.add(new_interface)
inheritance_stack = create_inheritance_stack(
old_interface, old_interfaces)
for interface in inheritance_stack[1:]:
......@@ -274,7 +275,6 @@ class IdlCompiler(object):
make_copy(operation) for operation in interface.operations
if is_own_member(operation)
])
self._ir_map.add(new_interface)
def _group_overloaded_functions(self):
old_irs = self._ir_map.irs_of_kinds(IRMap.IR.Kind.CALLBACK_INTERFACE,
......@@ -284,23 +284,80 @@ class IdlCompiler(object):
self._ir_map.move_to_new_phase()
for old_ir in old_irs:
assert not old_ir.operation_groups
assert not old_ir.constructor_groups
assert not old_ir.operation_groups
new_ir = make_copy(old_ir)
self._ir_map.add(new_ir)
sort_key = lambda x: x.identifier
new_ir.constructor_groups = [
ConstructorGroup.IR(constructors=list(constructors))
for identifier, constructors in itertools.groupby(
sorted(new_ir.constructors, key=sort_key), key=sort_key)
]
new_ir.operation_groups = [
OperationGroup.IR(operations=list(operations))
for identifier, operations in itertools.groupby(
sorted(new_ir.operations, key=sort_key), key=sort_key)
if identifier
]
new_ir.constructor_groups = [
ConstructorGroup.IR(constructors=list(constructors))
for identifier, constructors in itertools.groupby(
sorted(new_ir.constructors, key=sort_key), key=sort_key)
]
def _calculate_group_exposure(self):
old_irs = self._ir_map.irs_of_kinds(IRMap.IR.Kind.INTERFACE,
IRMap.IR.Kind.NAMESPACE)
self._ir_map.move_to_new_phase()
for old_ir in old_irs:
new_ir = make_copy(old_ir)
self._ir_map.add(new_ir)
for group in new_ir.constructor_groups + new_ir.operation_groups:
exposures = map(lambda overload: overload.exposure, group)
# [Exposed]
if any(not exposure.global_names_and_features
for exposure in exposures):
pass # Unconditionally exposed by default.
else:
for exposure in exposures:
for entry in exposure.global_names_and_features:
group.exposure.add_global_name_and_feature(
entry.global_name, entry.feature)
# [RuntimeEnabled]
if any(not exposure.runtime_enabled_features
for exposure in exposures):
pass # Unconditionally exposed by default.
else:
for exposure in exposures:
for name in exposure.runtime_enabled_features:
group.exposure.add_runtime_enabled_feature(name)
# [ContextEnabled]
if any(not exposure.context_enabled_features
for exposure in exposures):
pass # Unconditionally exposed by default.
else:
for exposure in exposures:
for name in exposure.context_enabled_features:
group.exposure.add_context_enabled_feature(name)
# [SecureContext]
if any(exposure.only_in_secure_contexts is False
for exposure in exposures):
group.exposure.set_only_in_secure_contexts(False)
elif all(exposure.only_in_secure_contexts is True
for exposure in exposures):
group.exposure.set_only_in_secure_contexts(True)
else:
flag_names = tuple(
itertools.chain.from_iterable([
exposure.only_in_secure_contexts
for exposure in exposures
if exposure.only_in_secure_contexts is not True
]))
group.exposure.set_only_in_secure_contexts(flag_names)
def _create_public_objects(self):
"""Creates public representations of compiled objects."""
for ir in self._ir_map.irs_of_kind(IRMap.IR.Kind.INTERFACE):
......
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