Chromium Code Reviews| 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..c02c8c7eba67b9e8b141ffe82135ad6c3a9084e8 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,81 @@ 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 |
| +class ExposureSet: |
| + '''An ExposureSet is a collection of Exposure instructions.''' |
| + def __init__(self, exposures=None): |
| + self.exposures = set(exposures) if exposures else set() |
| - interface_exposure_set = expanded_exposure_set_for_interface(interface) |
| + def issubset(self, other): |
| + '''Returns true if |self|'s exposure set is subset of |
| + |other|'s exposure set. This function doesn't case about |
| + RuntimeEnabled.''' |
| + self_set = set([e.exposed for e in self.exposures]) |
|
Jens Widell
2014/12/09 08:25:12
Nit: You can drop the [] here:
self_set = set(e
yhirano
2014/12/09 08:42:09
Done.
|
| + other_set = set([e.exposed for e in self.exposures]) |
| + self._extend(self_set) |
| + self._extend(other_set) |
| - # Methods must not be exposed to a broader scope than their interface. |
| - if not set(exposure_set).issubset(interface_exposure_set): |
| - raise ValueError('Interface members\' exposure sets must be a subset of the interface\'s.') |
| + return self_set.issubset(other_set) |
| + |
| + def _extend(self, target): |
| + workers = set(['DedicatedWorker', 'SharedWorker', 'ServiceWorker']) |
| + if workers.issubset(target): |
| + target.add('Worker') |
| + elif 'Worker' in target: |
| + target.update(workers) |
| - 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.') |
| + def add(self, exposure): |
| + self.exposures.add(exposure) |
| - exposure_checks.append('context->%s()' % EXPOSED_EXECUTION_CONTEXT_METHOD[environment]) |
| + def __len__(self): |
| + return len(self.exposures) |
| - return ' || '.join(exposure_checks) |
| + def __iter__(self): |
| + return self.exposures.__iter__() |
| + def _code(self, 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 expanded_exposure_set_for_interface(interface): |
| - exposure_set = extended_attribute_value_as_list(interface, '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])) |
|
Jens Widell
2014/12/09 08:25:12
Nit: Can drop the [] here as well.
yhirano
2014/12/09 08:42:09
Done.
|
| - # "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)) |
| +def exposed(definition_or_member, interface): |
| + '''Returns a C++ code that checks if a method/attribute/etc is exposed. |
|
Jens Widell
2014/12/09 08:25:12
Nit: Use """ instead of ''' for docstrings.
yhirano
2014/12/09 08:42:09
Done.
|
| + |
| + 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(definition_or_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 exposure_set.issubset(interface_exposure_set): |
| + raise ValueError('Interface members\' exposure sets must be a subset of the interface\'s.') |
| + |
| + return exposure_set.code() |
| # [GarbageCollected], [WillBeGarbageCollected] |