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): ...@@ -36,7 +36,7 @@ class Exposure(object):
self._global_names_and_features = tuple() self._global_names_and_features = tuple()
self._runtime_enabled_features = tuple() self._runtime_enabled_features = tuple()
self._context_enabled_features = tuple() self._context_enabled_features = tuple()
self._only_in_secure_contexts = False self._only_in_secure_contexts = None
@property @property
def global_names_and_features(self): def global_names_and_features(self):
...@@ -50,7 +50,7 @@ class Exposure(object): ...@@ -50,7 +50,7 @@ class Exposure(object):
def runtime_enabled_features(self): def runtime_enabled_features(self):
""" """
Returns a list of runtime enabled features. This construct is exposed 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 return self._runtime_enabled_features
...@@ -58,7 +58,7 @@ class Exposure(object): ...@@ -58,7 +58,7 @@ class Exposure(object):
def context_enabled_features(self): def context_enabled_features(self):
""" """
Returns a list of context enabled features. This construct is exposed 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 return self._context_enabled_features
...@@ -66,11 +66,14 @@ class Exposure(object): ...@@ -66,11 +66,14 @@ class Exposure(object):
def only_in_secure_contexts(self): def only_in_secure_contexts(self):
""" """
Returns whether this construct is available only in secure contexts or Returns whether this construct is available only in secure contexts or
not. The returned value will be either of a boolean (always true or not. The returned value is either of a boolean (True: unconditionally
false) or a flag name (only when the flag is enabled). 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 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 return self._only_in_secure_contexts
...@@ -81,7 +84,7 @@ class ExposureMutable(Exposure): ...@@ -81,7 +84,7 @@ class ExposureMutable(Exposure):
self._global_names_and_features = [] self._global_names_and_features = []
self._runtime_enabled_features = [] self._runtime_enabled_features = []
self._context_enabled_features = [] self._context_enabled_features = []
self._only_in_secure_contexts = False self._only_in_secure_contexts = None
def __getstate__(self): def __getstate__(self):
assert False, "ExposureMutable must not be pickled." assert False, "ExposureMutable must not be pickled."
...@@ -102,6 +105,13 @@ class ExposureMutable(Exposure): ...@@ -102,6 +105,13 @@ class ExposureMutable(Exposure):
self._context_enabled_features.append(name) self._context_enabled_features.append(name)
def set_only_in_secure_contexts(self, value): def set_only_in_secure_contexts(self, value):
assert isinstance(value, (bool, str)) assert (isinstance(value, (bool, str))
assert self._only_in_secure_contexts is False and value is not False or (isinstance(value, (list, tuple))
self._only_in_secure_contexts = value 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): ...@@ -91,6 +91,7 @@ class IdlCompiler(object):
# Make groups of overloaded functions including inherited ones. # Make groups of overloaded functions including inherited ones.
self._group_overloaded_functions() self._group_overloaded_functions()
self._calculate_group_exposure()
# Updates on IRs are finished. Create API objects. # Updates on IRs are finished. Create API objects.
self._create_public_objects() self._create_public_objects()
...@@ -150,6 +151,7 @@ class IdlCompiler(object): ...@@ -150,6 +151,7 @@ class IdlCompiler(object):
def process_interface_like(ir): def process_interface_like(ir):
ir = make_copy(ir) ir = make_copy(ir)
self._ir_map.add(ir)
propagate = functools.partial(propagate_extattr, ir=ir) propagate = functools.partial(propagate_extattr, ir=ir)
propagate(('ImplementedAs', 'set_receiver_implemented_as'), propagate(('ImplementedAs', 'set_receiver_implemented_as'),
...@@ -159,8 +161,6 @@ class IdlCompiler(object): ...@@ -159,8 +161,6 @@ class IdlCompiler(object):
map(process_member_like, ir.iter_all_members()) map(process_member_like, ir.iter_all_members())
self._ir_map.add(ir)
def process_member_like(ir): def process_member_like(ir):
propagate = functools.partial(propagate_extattr, ir=ir) propagate = functools.partial(propagate_extattr, ir=ir)
propagate(('ImplementedAs', 'set_property_implemented_as'), propagate(('ImplementedAs', 'set_property_implemented_as'),
...@@ -211,6 +211,7 @@ class IdlCompiler(object): ...@@ -211,6 +211,7 @@ class IdlCompiler(object):
for identifier, old_dictionary in old_dictionaries.iteritems(): for identifier, old_dictionary in old_dictionaries.iteritems():
new_dictionary = make_copy(old_dictionary) new_dictionary = make_copy(old_dictionary)
self._ir_map.add(new_dictionary)
for partial_dictionary in old_partial_dictionaries.get( for partial_dictionary in old_partial_dictionaries.get(
identifier, []): identifier, []):
new_dictionary.add_components(partial_dictionary.components) new_dictionary.add_components(partial_dictionary.components)
...@@ -218,7 +219,6 @@ class IdlCompiler(object): ...@@ -218,7 +219,6 @@ class IdlCompiler(object):
partial_dictionary.debug_info.all_locations) partial_dictionary.debug_info.all_locations)
new_dictionary.own_members.extend( new_dictionary.own_members.extend(
make_copy(partial_dictionary.own_members)) make_copy(partial_dictionary.own_members))
self._ir_map.add(new_dictionary)
def _merge_interface_mixins(self): def _merge_interface_mixins(self):
interfaces = self._ir_map.find_by_kind(IRMap.IR.Kind.INTERFACE) interfaces = self._ir_map.find_by_kind(IRMap.IR.Kind.INTERFACE)
...@@ -237,6 +237,7 @@ class IdlCompiler(object): ...@@ -237,6 +237,7 @@ class IdlCompiler(object):
def _merge_interface_like_irs(self, old_irs_to_merge): def _merge_interface_like_irs(self, old_irs_to_merge):
for old_ir, irs_to_be_merged in old_irs_to_merge: for old_ir, irs_to_be_merged in old_irs_to_merge:
new_ir = make_copy(old_ir) new_ir = make_copy(old_ir)
self._ir_map.add(new_ir)
for ir in irs_to_be_merged: for ir in irs_to_be_merged:
to_be_merged = make_copy(ir) to_be_merged = make_copy(ir)
new_ir.add_components(to_be_merged.components) new_ir.add_components(to_be_merged.components)
...@@ -245,7 +246,6 @@ class IdlCompiler(object): ...@@ -245,7 +246,6 @@ class IdlCompiler(object):
new_ir.attributes.extend(to_be_merged.attributes) new_ir.attributes.extend(to_be_merged.attributes)
new_ir.constants.extend(to_be_merged.constants) new_ir.constants.extend(to_be_merged.constants)
new_ir.operations.extend(to_be_merged.operations) new_ir.operations.extend(to_be_merged.operations)
self._ir_map.add(new_ir)
def _process_interface_inheritances(self): def _process_interface_inheritances(self):
def is_own_member(member): def is_own_member(member):
...@@ -263,6 +263,7 @@ class IdlCompiler(object): ...@@ -263,6 +263,7 @@ class IdlCompiler(object):
for old_interface in old_interfaces.itervalues(): for old_interface in old_interfaces.itervalues():
new_interface = make_copy(old_interface) new_interface = make_copy(old_interface)
self._ir_map.add(new_interface)
inheritance_stack = create_inheritance_stack( inheritance_stack = create_inheritance_stack(
old_interface, old_interfaces) old_interface, old_interfaces)
for interface in inheritance_stack[1:]: for interface in inheritance_stack[1:]:
...@@ -274,7 +275,6 @@ class IdlCompiler(object): ...@@ -274,7 +275,6 @@ class IdlCompiler(object):
make_copy(operation) for operation in interface.operations make_copy(operation) for operation in interface.operations
if is_own_member(operation) if is_own_member(operation)
]) ])
self._ir_map.add(new_interface)
def _group_overloaded_functions(self): def _group_overloaded_functions(self):
old_irs = self._ir_map.irs_of_kinds(IRMap.IR.Kind.CALLBACK_INTERFACE, old_irs = self._ir_map.irs_of_kinds(IRMap.IR.Kind.CALLBACK_INTERFACE,
...@@ -284,23 +284,80 @@ class IdlCompiler(object): ...@@ -284,23 +284,80 @@ class IdlCompiler(object):
self._ir_map.move_to_new_phase() self._ir_map.move_to_new_phase()
for old_ir in old_irs: for old_ir in old_irs:
assert not old_ir.operation_groups
assert not old_ir.constructor_groups assert not old_ir.constructor_groups
assert not old_ir.operation_groups
new_ir = make_copy(old_ir) new_ir = make_copy(old_ir)
self._ir_map.add(new_ir)
sort_key = lambda x: x.identifier 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 = [ new_ir.operation_groups = [
OperationGroup.IR(operations=list(operations)) OperationGroup.IR(operations=list(operations))
for identifier, operations in itertools.groupby( for identifier, operations in itertools.groupby(
sorted(new_ir.operations, key=sort_key), key=sort_key) sorted(new_ir.operations, key=sort_key), key=sort_key)
if identifier if identifier
] ]
new_ir.constructor_groups = [
ConstructorGroup.IR(constructors=list(constructors)) def _calculate_group_exposure(self):
for identifier, constructors in itertools.groupby( old_irs = self._ir_map.irs_of_kinds(IRMap.IR.Kind.INTERFACE,
sorted(new_ir.constructors, key=sort_key), key=sort_key) 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) 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): def _create_public_objects(self):
"""Creates public representations of compiled objects.""" """Creates public representations of compiled objects."""
for ir in self._ir_map.irs_of_kind(IRMap.IR.Kind.INTERFACE): 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