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 | |
264 |other|'s exposure set. This function doesn't case about | |
265 RuntimeEnabled.""" | |
266 self_set = set(e.exposed for e in self.exposures) | |
267 other_set = set(e.exposed for e in self.exposures) | |
Jens Widell
2014/12/09 11:30:31
"self.exposures" => "other.exposures"
yhirano
2014/12/09 11:59:13
Done.
| |
268 self._extend(self_set) | |
269 self._extend(other_set) | |
270 | |
271 return self_set.issubset(other_set) | |
272 | |
273 def _extend(self, target): | |
Jens Widell
2014/12/09 11:30:31
I'd make this method static, name it "extended" in
yhirano
2014/12/09 11:59:13
Done.
| |
274 workers = set(['DedicatedWorker', 'SharedWorker', 'ServiceWorker']) | |
275 if workers.issubset(target): | |
276 target.add('Worker') | |
277 elif 'Worker' in target: | |
278 target.update(workers) | |
279 | |
280 def add(self, exposure): | |
281 self.exposures.add(exposure) | |
282 | |
283 def __len__(self): | |
284 return len(self.exposures) | |
285 | |
286 def __iter__(self): | |
287 return self.exposures.__iter__() | |
288 | |
289 def _code(self, exposure): | |
Jens Widell
2014/12/09 11:30:31
Make this method static too?
yhirano
2014/12/09 11:59:13
Done.
| |
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): |
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() | |
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 |