| Index: Source/bindings/scripts/v8_utilities.py
|
| diff --git a/Source/bindings/scripts/v8_utilities.py b/Source/bindings/scripts/v8_utilities.py
|
| index 01d16f748044b8d64911505794179be7af56de4d..c4935d79d17f692a3c5eba27ac07d598fc5a8d93 100644
|
| --- a/Source/bindings/scripts/v8_utilities.py
|
| +++ b/Source/bindings/scripts/v8_utilities.py
|
| @@ -37,6 +37,7 @@ import re
|
|
|
| from idl_types import IdlTypeBase
|
| import idl_types
|
| +from idl_definitions import Exposure
|
| from v8_globals import includes
|
| import v8_types
|
|
|
| @@ -253,36 +254,87 @@ EXPOSED_EXECUTION_CONTEXT_METHOD = {
|
| }
|
|
|
|
|
| -def exposed(definition_or_member, interface):
|
| - exposure_set = extended_attribute_value_as_list(definition_or_member, 'Exposed')
|
| - if not exposure_set:
|
| - return None
|
| -
|
| - interface_exposure_set = expanded_exposure_set_for_interface(interface)
|
| +EXPOSED_WORKERS = set([
|
| + 'DedicatedWorker',
|
| + 'SharedWorker',
|
| + 'ServiceWorker',
|
| +])
|
| +
|
| +
|
| +class ExposureSet:
|
| + """An ExposureSet is a collection of Exposure instructions."""
|
| + def __init__(self, exposures=None):
|
| + self.exposures = set(exposures) if exposures else set()
|
| +
|
| + def issubset(self, other):
|
| + """Returns true if |self|'s exposure set is a subset of
|
| + |other|'s exposure set. This function doesn't care about
|
| + RuntimeEnabled."""
|
| + self_set = self._extended(set(e.exposed for e in self.exposures))
|
| + other_set = self._extended(set(e.exposed for e in other.exposures))
|
| + return self_set.issubset(other_set)
|
| +
|
| + @staticmethod
|
| + def _extended(target):
|
| + if EXPOSED_WORKERS.issubset(target):
|
| + return target | set(['Worker'])
|
| + elif 'Worker' in target:
|
| + return target | EXPOSED_WORKERS
|
| + return target
|
| +
|
| + def add(self, exposure):
|
| + self.exposures.add(exposure)
|
| +
|
| + def __len__(self):
|
| + return len(self.exposures)
|
| +
|
| + def __iter__(self):
|
| + return self.exposures.__iter__()
|
| +
|
| + @staticmethod
|
| + def _code(exposure):
|
| + exposed = ('context->%s()' %
|
| + EXPOSED_EXECUTION_CONTEXT_METHOD[exposure.exposed])
|
| + if exposure.runtime_enabled is not None:
|
| + runtime_enabled = ('RuntimeEnabledFeatures::%sEnabled()' %
|
| + uncapitalize(exposure.runtime_enabled))
|
| + return '({0} && {1})'.format(exposed, runtime_enabled)
|
| + return exposed
|
| +
|
| + def code(self):
|
| + if len(self.exposures) == 0:
|
| + return None
|
| + # We use sorted here to deflake output.
|
| + return ' || '.join(sorted(self._code(e) for e in self.exposures))
|
| +
|
| +
|
| +def exposed(member, interface):
|
| + """Returns a C++ code that checks if a method/attribute/etc is exposed.
|
| +
|
| + When the Exposed attribute contains RuntimeEnabledFeatures (i.e.
|
| + Exposed(Arguments) form is given), the code contains check for them as
|
| + well.
|
| +
|
| + EXAMPLE: [Exposed=Window, RuntimeEnabledFeature=Feature1]
|
| + => context->isDocument()
|
| +
|
| + EXAMPLE: [Exposed(Window Feature1, Window Feature2)]
|
| + => context->isDocument() && RuntimeEnabledFeatures::feature1Enabled() ||
|
| + context->isDocument() && RuntimeEnabledFeatures::feature2Enabled()
|
| + """
|
| + exposure_set = ExposureSet(
|
| + extended_attribute_value_as_list(member, 'Exposed'))
|
| + interface_exposure_set = ExposureSet(
|
| + extended_attribute_value_as_list(interface, 'Exposed'))
|
| + for e in exposure_set:
|
| + if e.exposed not in EXPOSED_EXECUTION_CONTEXT_METHOD:
|
| + raise ValueError('Invalid execution context: %s' % e.exposed)
|
|
|
| # Methods must not be exposed to a broader scope than their interface.
|
| - if not set(exposure_set).issubset(interface_exposure_set):
|
| + if not exposure_set.issubset(interface_exposure_set):
|
| raise ValueError('Interface members\' exposure sets must be a subset of the interface\'s.')
|
|
|
| - exposure_checks = []
|
| - for environment in exposure_set:
|
| - # Methods must be exposed on one of the scopes known to Blink.
|
| - if environment not in EXPOSED_EXECUTION_CONTEXT_METHOD:
|
| - raise ValueError('Values for the [Exposed] annotation must reflect to a valid exposure scope.')
|
| -
|
| - exposure_checks.append('context->%s()' % EXPOSED_EXECUTION_CONTEXT_METHOD[environment])
|
| -
|
| - return ' || '.join(exposure_checks)
|
| -
|
| -
|
| -def expanded_exposure_set_for_interface(interface):
|
| - exposure_set = extended_attribute_value_as_list(interface, 'Exposed')
|
| -
|
| - # "Worker" is an aggregation for the different kinds of workers.
|
| - if 'Worker' in exposure_set:
|
| - exposure_set.extend(('DedicatedWorker', 'SharedWorker', 'ServiceWorker'))
|
| -
|
| - return sorted(set(exposure_set))
|
| + return exposure_set.code()
|
|
|
|
|
| # [GarbageCollected], [WillBeGarbageCollected]
|
|
|