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..ccb35d472f3adbbe0003c27475333719d30ddc79 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 |
| - |
| - interface_exposure_set = expanded_exposure_set_for_interface(interface) |
| - |
| - # 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.') |
| +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 subset of |
|
haraken
2014/12/09 16:07:56
a subset
yhirano
2014/12/11 01:38:25
Done.
|
| + |other|'s exposure set. This function doesn't case about |
|
haraken
2014/12/09 16:07:56
care about
yhirano
2014/12/11 01:38:25
Done.
|
| + 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): |
| + workers = set(['DedicatedWorker', 'SharedWorker', 'ServiceWorker']) |
|
bashi
2014/12/09 23:42:19
I prefer putting this set next to EXPOSED_EXECUTIO
yhirano
2014/12/11 01:38:25
Done.
|
| + if workers.issubset(target): |
| + return target | set(['Worker']) |
| + elif 'Worker' in target: |
| + return target | 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)) |
| - 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]) |
| +def exposed(definition_or_member, interface): |
|
haraken
2014/12/09 16:07:56
What does 'definition' mean? It looks a bit confus
Jens Widell
2014/12/09 16:19:23
Yeah, it ought to just be 'member'.
[Exposed] is
yhirano
2014/12/11 01:38:25
Done.
|
| + """Returns a C++ code that checks if a method/attribute/etc is exposed. |
| - return ' || '.join(exposure_checks) |
| + 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() |
|
haraken
2014/12/09 16:07:56
context->isDocument() && RuntimeEnabledFeatures::f
Jens Widell
2014/12/09 16:19:23
While that's the actual logic in the end, it's not
yhirano
2014/12/11 01:38:25
Yeah, so I would like to leave it be.
|
| -def expanded_exposure_set_for_interface(interface): |
| - exposure_set = extended_attribute_value_as_list(interface, 'Exposed') |
| + 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) |
| - # "Worker" is an aggregation for the different kinds of workers. |
| - if 'Worker' in exposure_set: |
| - exposure_set.extend(('DedicatedWorker', 'SharedWorker', 'ServiceWorker')) |
| + # 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 sorted(set(exposure_set)) |
| + return exposure_set.code() |
| # [GarbageCollected], [WillBeGarbageCollected] |