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 |
256 def exposed(definition_or_member, interface): | 257 EXPOSED_WORKERS = set([ |
257 exposure_set = extended_attribute_value_as_list(definition_or_member, 'Expos
ed') | 258 'DedicatedWorker', |
258 if not exposure_set: | 259 'SharedWorker', |
259 return None | 260 'ServiceWorker', |
| 261 ]) |
260 | 262 |
261 interface_exposure_set = expanded_exposure_set_for_interface(interface) | 263 |
| 264 class ExposureSet: |
| 265 """An ExposureSet is a collection of Exposure instructions.""" |
| 266 def __init__(self, exposures=None): |
| 267 self.exposures = set(exposures) if exposures else set() |
| 268 |
| 269 def issubset(self, other): |
| 270 """Returns true if |self|'s exposure set is a subset of |
| 271 |other|'s exposure set. This function doesn't care about |
| 272 RuntimeEnabled.""" |
| 273 self_set = self._extended(set(e.exposed for e in self.exposures)) |
| 274 other_set = self._extended(set(e.exposed for e in other.exposures)) |
| 275 return self_set.issubset(other_set) |
| 276 |
| 277 @staticmethod |
| 278 def _extended(target): |
| 279 if EXPOSED_WORKERS.issubset(target): |
| 280 return target | set(['Worker']) |
| 281 elif 'Worker' in target: |
| 282 return target | EXPOSED_WORKERS |
| 283 return target |
| 284 |
| 285 def add(self, exposure): |
| 286 self.exposures.add(exposure) |
| 287 |
| 288 def __len__(self): |
| 289 return len(self.exposures) |
| 290 |
| 291 def __iter__(self): |
| 292 return self.exposures.__iter__() |
| 293 |
| 294 @staticmethod |
| 295 def _code(exposure): |
| 296 exposed = ('context->%s()' % |
| 297 EXPOSED_EXECUTION_CONTEXT_METHOD[exposure.exposed]) |
| 298 if exposure.runtime_enabled is not None: |
| 299 runtime_enabled = ('RuntimeEnabledFeatures::%sEnabled()' % |
| 300 uncapitalize(exposure.runtime_enabled)) |
| 301 return '({0} && {1})'.format(exposed, runtime_enabled) |
| 302 return exposed |
| 303 |
| 304 def code(self): |
| 305 if len(self.exposures) == 0: |
| 306 return None |
| 307 # We use sorted here to deflake output. |
| 308 return ' || '.join(sorted(self._code(e) for e in self.exposures)) |
| 309 |
| 310 |
| 311 def exposed(member, interface): |
| 312 """Returns a C++ code that checks if a method/attribute/etc is exposed. |
| 313 |
| 314 When the Exposed attribute contains RuntimeEnabledFeatures (i.e. |
| 315 Exposed(Arguments) form is given), the code contains check for them as |
| 316 well. |
| 317 |
| 318 EXAMPLE: [Exposed=Window, RuntimeEnabledFeature=Feature1] |
| 319 => context->isDocument() |
| 320 |
| 321 EXAMPLE: [Exposed(Window Feature1, Window Feature2)] |
| 322 => context->isDocument() && RuntimeEnabledFeatures::feature1Enabled() || |
| 323 context->isDocument() && RuntimeEnabledFeatures::feature2Enabled() |
| 324 """ |
| 325 exposure_set = ExposureSet( |
| 326 extended_attribute_value_as_list(member, 'Exposed')) |
| 327 interface_exposure_set = ExposureSet( |
| 328 extended_attribute_value_as_list(interface, 'Exposed')) |
| 329 for e in exposure_set: |
| 330 if e.exposed not in EXPOSED_EXECUTION_CONTEXT_METHOD: |
| 331 raise ValueError('Invalid execution context: %s' % e.exposed) |
262 | 332 |
263 # Methods must not be exposed to a broader scope than their interface. | 333 # Methods must not be exposed to a broader scope than their interface. |
264 if not set(exposure_set).issubset(interface_exposure_set): | 334 if not exposure_set.issubset(interface_exposure_set): |
265 raise ValueError('Interface members\' exposure sets must be a subset of
the interface\'s.') | 335 raise ValueError('Interface members\' exposure sets must be a subset of
the interface\'s.') |
266 | 336 |
267 exposure_checks = [] | 337 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 | 338 |
287 | 339 |
288 # [GarbageCollected], [WillBeGarbageCollected] | 340 # [GarbageCollected], [WillBeGarbageCollected] |
289 def gc_type(definition): | 341 def gc_type(definition): |
290 extended_attributes = definition.extended_attributes | 342 extended_attributes = definition.extended_attributes |
291 if 'GarbageCollected' in extended_attributes: | 343 if 'GarbageCollected' in extended_attributes: |
292 return 'GarbageCollectedObject' | 344 return 'GarbageCollectedObject' |
293 elif 'WillBeGarbageCollected' in extended_attributes: | 345 elif 'WillBeGarbageCollected' in extended_attributes: |
294 return 'WillBeGarbageCollectedObject' | 346 return 'WillBeGarbageCollectedObject' |
295 return 'RefCountedObject' | 347 return 'RefCountedObject' |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 | 390 |
339 The returned function checks if a method/attribute is enabled. | 391 The returned function checks if a method/attribute is enabled. |
340 Given extended attribute RuntimeEnabled=FeatureName, return: | 392 Given extended attribute RuntimeEnabled=FeatureName, return: |
341 RuntimeEnabledFeatures::{featureName}Enabled | 393 RuntimeEnabledFeatures::{featureName}Enabled |
342 """ | 394 """ |
343 extended_attributes = definition_or_member.extended_attributes | 395 extended_attributes = definition_or_member.extended_attributes |
344 if 'RuntimeEnabled' not in extended_attributes: | 396 if 'RuntimeEnabled' not in extended_attributes: |
345 return None | 397 return None |
346 feature_name = extended_attributes['RuntimeEnabled'] | 398 feature_name = extended_attributes['RuntimeEnabled'] |
347 return 'RuntimeEnabledFeatures::%sEnabled' % uncapitalize(feature_name) | 399 return 'RuntimeEnabledFeatures::%sEnabled' % uncapitalize(feature_name) |
OLD | NEW |