Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (C) 2013 Google Inc. All rights reserved. | 1 # Copyright (C) 2013 Google Inc. All rights reserved. |
| 2 # | 2 # |
| 3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
| 4 # modification, are permitted provided that the following conditions are | 4 # modification, are permitted provided that the following conditions are |
| 5 # met: | 5 # met: |
| 6 # | 6 # |
| 7 # * Redistributions of source code must retain the above copyright | 7 # * Redistributions of source code must retain the above copyright |
| 8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
| 9 # * Redistributions in binary form must reproduce the above | 9 # * Redistributions in binary form must reproduce the above |
| 10 # copyright notice, this list of conditions and the following disclaimer | 10 # copyright notice, this list of conditions and the following disclaimer |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 30 | 30 |
| 31 Extends IdlTypeBase type with |enum_validation_expression| property. | 31 Extends IdlTypeBase type with |enum_validation_expression| property. |
| 32 | 32 |
| 33 Design doc: http://www.chromium.org/developers/design-documents/idl-compiler | 33 Design doc: http://www.chromium.org/developers/design-documents/idl-compiler |
| 34 """ | 34 """ |
| 35 | 35 |
| 36 import re | 36 import re |
| 37 | 37 |
| 38 from idl_types import IdlTypeBase | 38 from idl_types import IdlTypeBase |
| 39 import idl_types | 39 import idl_types |
| 40 from idl_definitions import Exposure | |
| 40 from v8_globals import includes | 41 from v8_globals import includes |
| 41 import v8_types | 42 import v8_types |
| 42 | 43 |
| 43 ACRONYMS = [ | 44 ACRONYMS = [ |
| 44 'CSSOM', # must come *before* CSS to match full acronym | 45 'CSSOM', # must come *before* CSS to match full acronym |
| 45 'CSS', | 46 'CSS', |
| 46 'HTML', | 47 'HTML', |
| 47 'IME', | 48 'IME', |
| 48 'JS', | 49 'JS', |
| 49 'SVG', | 50 'SVG', |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 246 # [Exposed] | 247 # [Exposed] |
| 247 EXPOSED_EXECUTION_CONTEXT_METHOD = { | 248 EXPOSED_EXECUTION_CONTEXT_METHOD = { |
| 248 'DedicatedWorker': 'isDedicatedWorkerGlobalScope', | 249 'DedicatedWorker': 'isDedicatedWorkerGlobalScope', |
| 249 'ServiceWorker': 'isServiceWorkerGlobalScope', | 250 'ServiceWorker': 'isServiceWorkerGlobalScope', |
| 250 'SharedWorker': 'isSharedWorkerGlobalScope', | 251 'SharedWorker': 'isSharedWorkerGlobalScope', |
| 251 'Window': 'isDocument', | 252 'Window': 'isDocument', |
| 252 'Worker': 'isWorkerGlobalScope', | 253 'Worker': 'isWorkerGlobalScope', |
| 253 } | 254 } |
| 254 | 255 |
| 255 | 256 |
| 257 class ExposureSet: | |
| 258 """An ExposureSet is a collection of Exposure instructions.""" | |
| 259 def __init__(self, exposures=None): | |
| 260 self.exposures = set(exposures) if exposures else set() | |
| 261 | |
| 262 def issubset(self, other): | |
| 263 """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.
| |
| 264 |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.
| |
| 265 RuntimeEnabled.""" | |
| 266 self_set = self._extended(set(e.exposed for e in self.exposures)) | |
| 267 other_set = self._extended(set(e.exposed for e in other.exposures)) | |
| 268 return self_set.issubset(other_set) | |
| 269 | |
| 270 @staticmethod | |
| 271 def _extended(target): | |
| 272 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.
| |
| 273 if workers.issubset(target): | |
| 274 return target | set(['Worker']) | |
| 275 elif 'Worker' in target: | |
| 276 return target | workers | |
| 277 return target | |
| 278 | |
| 279 def add(self, exposure): | |
| 280 self.exposures.add(exposure) | |
| 281 | |
| 282 def __len__(self): | |
| 283 return len(self.exposures) | |
| 284 | |
| 285 def __iter__(self): | |
| 286 return self.exposures.__iter__() | |
| 287 | |
| 288 @staticmethod | |
| 289 def _code(exposure): | |
| 290 exposed = ('context->%s()' % | |
| 291 EXPOSED_EXECUTION_CONTEXT_METHOD[exposure.exposed]) | |
| 292 if exposure.runtime_enabled is not None: | |
| 293 runtime_enabled = ('RuntimeEnabledFeatures::%sEnabled()' % | |
| 294 uncapitalize(exposure.runtime_enabled)) | |
| 295 return '({0} && {1})'.format(exposed, runtime_enabled) | |
| 296 return exposed | |
| 297 | |
| 298 def code(self): | |
| 299 if len(self.exposures) == 0: | |
| 300 return None | |
| 301 # We use sorted here to deflake output. | |
| 302 return ' || '.join(sorted(self._code(e) for e in self.exposures)) | |
| 303 | |
| 304 | |
| 256 def exposed(definition_or_member, interface): | 305 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.
| |
| 257 exposure_set = extended_attribute_value_as_list(definition_or_member, 'Expos ed') | 306 """Returns a C++ code that checks if a method/attribute/etc is exposed. |
| 258 if not exposure_set: | |
| 259 return None | |
| 260 | 307 |
| 261 interface_exposure_set = expanded_exposure_set_for_interface(interface) | 308 When the Exposed attribute contains RuntimeEnabledFeatures (i.e. |
| 309 Exposed(Arguments) form is given), the code contains check for them as | |
| 310 well. | |
| 311 | |
| 312 EXAMPLE: [Exposed=Window, RuntimeEnabledFeature=Feature1] | |
| 313 => 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.
| |
| 314 | |
| 315 EXAMPLE: [Exposed(Window Feature1, Window Feature2)] | |
| 316 => context->isDocument() && RuntimeEnabledFeatures::feature1Enabled() || | |
| 317 context->isDocument() && RuntimeEnabledFeatures::feature2Enabled() | |
| 318 """ | |
| 319 exposure_set = ExposureSet( | |
| 320 extended_attribute_value_as_list(definition_or_member, 'Exposed')) | |
| 321 interface_exposure_set = ExposureSet( | |
| 322 extended_attribute_value_as_list(interface, 'Exposed')) | |
| 323 for e in exposure_set: | |
| 324 if e.exposed not in EXPOSED_EXECUTION_CONTEXT_METHOD: | |
| 325 raise ValueError('Invalid execution context: %s' % e.exposed) | |
| 262 | 326 |
| 263 # Methods must not be exposed to a broader scope than their interface. | 327 # Methods must not be exposed to a broader scope than their interface. |
| 264 if not set(exposure_set).issubset(interface_exposure_set): | 328 if not exposure_set.issubset(interface_exposure_set): |
| 265 raise ValueError('Interface members\' exposure sets must be a subset of the interface\'s.') | 329 raise ValueError('Interface members\' exposure sets must be a subset of the interface\'s.') |
| 266 | 330 |
| 267 exposure_checks = [] | 331 return exposure_set.code() |
| 268 for environment in exposure_set: | |
| 269 # Methods must be exposed on one of the scopes known to Blink. | |
| 270 if environment not in EXPOSED_EXECUTION_CONTEXT_METHOD: | |
| 271 raise ValueError('Values for the [Exposed] annotation must reflect t o a valid exposure scope.') | |
| 272 | |
| 273 exposure_checks.append('context->%s()' % EXPOSED_EXECUTION_CONTEXT_METHO D[environment]) | |
| 274 | |
| 275 return ' || '.join(exposure_checks) | |
| 276 | |
| 277 | |
| 278 def expanded_exposure_set_for_interface(interface): | |
| 279 exposure_set = extended_attribute_value_as_list(interface, 'Exposed') | |
| 280 | |
| 281 # "Worker" is an aggregation for the different kinds of workers. | |
| 282 if 'Worker' in exposure_set: | |
| 283 exposure_set.extend(('DedicatedWorker', 'SharedWorker', 'ServiceWorker') ) | |
| 284 | |
| 285 return sorted(set(exposure_set)) | |
| 286 | 332 |
| 287 | 333 |
| 288 # [GarbageCollected], [WillBeGarbageCollected] | 334 # [GarbageCollected], [WillBeGarbageCollected] |
| 289 def gc_type(definition): | 335 def gc_type(definition): |
| 290 extended_attributes = definition.extended_attributes | 336 extended_attributes = definition.extended_attributes |
| 291 if 'GarbageCollected' in extended_attributes: | 337 if 'GarbageCollected' in extended_attributes: |
| 292 return 'GarbageCollectedObject' | 338 return 'GarbageCollectedObject' |
| 293 elif 'WillBeGarbageCollected' in extended_attributes: | 339 elif 'WillBeGarbageCollected' in extended_attributes: |
| 294 return 'WillBeGarbageCollectedObject' | 340 return 'WillBeGarbageCollectedObject' |
| 295 return 'RefCountedObject' | 341 return 'RefCountedObject' |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 338 | 384 |
| 339 The returned function checks if a method/attribute is enabled. | 385 The returned function checks if a method/attribute is enabled. |
| 340 Given extended attribute RuntimeEnabled=FeatureName, return: | 386 Given extended attribute RuntimeEnabled=FeatureName, return: |
| 341 RuntimeEnabledFeatures::{featureName}Enabled | 387 RuntimeEnabledFeatures::{featureName}Enabled |
| 342 """ | 388 """ |
| 343 extended_attributes = definition_or_member.extended_attributes | 389 extended_attributes = definition_or_member.extended_attributes |
| 344 if 'RuntimeEnabled' not in extended_attributes: | 390 if 'RuntimeEnabled' not in extended_attributes: |
| 345 return None | 391 return None |
| 346 feature_name = extended_attributes['RuntimeEnabled'] | 392 feature_name = extended_attributes['RuntimeEnabled'] |
| 347 return 'RuntimeEnabledFeatures::%sEnabled' % uncapitalize(feature_name) | 393 return 'RuntimeEnabledFeatures::%sEnabled' % uncapitalize(feature_name) |
| OLD | NEW |