Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / bindings / scripts / v8_utilities.py
1 # Copyright (C) 2013 Google Inc. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are
5 # met:
6 #
7 #     * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer.
9 #     * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following disclaimer
11 # in the documentation and/or other materials provided with the
12 # distribution.
13 #     * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived from
15 # this software without specific prior written permission.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 """Functions shared by various parts of the code generator.
30
31 Extends IdlTypeBase type with |enum_validation_expression| property.
32
33 Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
34 """
35
36 import re
37
38 from idl_types import IdlTypeBase
39 import idl_types
40 from v8_globals import includes
41 import v8_types
42
43 ACRONYMS = [
44     'CSSOM',  # must come *before* CSS to match full acronym
45     'CSS',
46     'HTML',
47     'IME',
48     'JS',
49     'SVG',
50     'URL',
51     'WOFF',
52     'XML',
53     'XSLT',
54 ]
55
56
57 ################################################################################
58 # Extended attribute parsing
59 ################################################################################
60
61 def extended_attribute_value_contains(extended_attribute_value, key):
62     return (extended_attribute_value == key or
63             (isinstance(extended_attribute_value, list) and
64              key in extended_attribute_value))
65
66
67 def has_extended_attribute(definition_or_member, extended_attribute_list):
68     return any(extended_attribute in definition_or_member.extended_attributes
69                for extended_attribute in extended_attribute_list)
70
71
72 def has_extended_attribute_value(definition_or_member, name, value):
73     extended_attributes = definition_or_member.extended_attributes
74     return (name in extended_attributes and
75             extended_attribute_value_contains(extended_attributes[name], value))
76
77
78 def extended_attribute_value_as_list(definition_or_member, name):
79     extended_attributes = definition_or_member.extended_attributes
80     if name not in extended_attributes:
81         return None
82     value = extended_attributes[name]
83     if isinstance(value, list):
84         return value
85     return [value]
86
87
88 ################################################################################
89 # String handling
90 ################################################################################
91
92 def capitalize(name):
93     """Capitalize first letter or initial acronym (used in setter names)."""
94     for acronym in ACRONYMS:
95         if name.startswith(acronym.lower()):
96             return name.replace(acronym.lower(), acronym)
97     return name[0].upper() + name[1:]
98
99
100 def strip_suffix(string, suffix):
101     if not suffix or not string.endswith(suffix):
102         return string
103     return string[:-len(suffix)]
104
105
106 def uncapitalize(name):
107     """Uncapitalizes first letter or initial acronym (used in method names).
108
109     E.g., 'SetURL' becomes 'setURL', but 'URLFoo' becomes 'urlFoo'.
110     """
111     for acronym in ACRONYMS:
112         if name.startswith(acronym):
113             return name.replace(acronym, acronym.lower())
114     return name[0].lower() + name[1:]
115
116
117 ################################################################################
118 # C++
119 ################################################################################
120
121 def enum_validation_expression(idl_type):
122     # FIXME: Add IdlEnumType, move property to derived type, and remove this check
123     if not idl_type.is_enum:
124         return None
125     return ' || '.join(['string == "%s"' % enum_value
126                         for enum_value in idl_type.enum_values])
127 IdlTypeBase.enum_validation_expression = property(enum_validation_expression)
128
129
130 def scoped_name(interface, definition, base_name):
131     if 'ImplementedInPrivateScript' in definition.extended_attributes:
132         return '%s::PrivateScript::%s' % (v8_class_name(interface), base_name)
133     # partial interfaces are implemented as separate classes, with their members
134     # implemented as static member functions
135     partial_interface_implemented_as = definition.extended_attributes.get('PartialInterfaceImplementedAs')
136     if partial_interface_implemented_as:
137         return '%s::%s' % (partial_interface_implemented_as, base_name)
138     if (definition.is_static or
139         definition.name in ('Constructor', 'NamedConstructor')):
140         return '%s::%s' % (cpp_name(interface), base_name)
141     return 'impl->%s' % base_name
142
143
144 def v8_class_name(interface):
145     return v8_types.v8_type(interface.name)
146
147
148 def v8_class_name_or_partial(interface):
149     class_name = v8_class_name(interface)
150     if interface.is_partial:
151         return ''.join([class_name, 'Partial'])
152     return class_name
153
154
155 ################################################################################
156 # Specific extended attributes
157 ################################################################################
158
159 # [ActivityLogging]
160 def activity_logging_world_list(member, access_type=''):
161     """Returns a set of world suffixes for which a definition member has activity logging, for specified access type.
162
163     access_type can be 'Getter' or 'Setter' if only checking getting or setting.
164     """
165     extended_attributes = member.extended_attributes
166     if 'LogActivity' not in extended_attributes:
167         return set()
168     log_activity = extended_attributes['LogActivity']
169     if log_activity and not log_activity.startswith(access_type):
170         return set()
171
172     includes.add('bindings/core/v8/V8DOMActivityLogger.h')
173     if 'LogAllWorlds' in extended_attributes:
174         return set(['', 'ForMainWorld'])
175     return set([''])  # At minimum, include isolated worlds.
176
177
178 # [ActivityLogging]
179 def activity_logging_world_check(member):
180     """Returns if an isolated world check is required when generating activity
181     logging code.
182
183     The check is required when there is no per-world binding code and logging is
184     required only for isolated world.
185     """
186     extended_attributes = member.extended_attributes
187     if 'LogActivity' not in extended_attributes:
188         return False
189     if ('PerWorldBindings' not in extended_attributes and
190         'LogAllWorlds' not in extended_attributes):
191         return True
192     return False
193
194
195 # [CallWith]
196 CALL_WITH_ARGUMENTS = {
197     'ScriptState': 'scriptState',
198     'ExecutionContext': 'executionContext',
199     'ScriptArguments': 'scriptArguments.release()',
200     'ActiveWindow': 'callingDOMWindow(info.GetIsolate())',
201     'FirstWindow': 'enteredDOMWindow(info.GetIsolate())',
202     'Document': 'document',
203 }
204 # List because key order matters, as we want arguments in deterministic order
205 CALL_WITH_VALUES = [
206     'ScriptState',
207     'ExecutionContext',
208     'ScriptArguments',
209     'ActiveWindow',
210     'FirstWindow',
211     'Document',
212 ]
213
214
215 def call_with_arguments(call_with_values):
216     if not call_with_values:
217         return []
218     return [CALL_WITH_ARGUMENTS[value]
219             for value in CALL_WITH_VALUES
220             if extended_attribute_value_contains(call_with_values, value)]
221
222
223 # [Conditional]
224 DELIMITER_TO_OPERATOR = {
225     '|': '||',
226     ',': '&&',
227 }
228
229
230 def conditional_string(definition_or_member):
231     extended_attributes = definition_or_member.extended_attributes
232     if 'Conditional' not in extended_attributes:
233         return None
234     return 'ENABLE(%s)' % extended_attributes['Conditional']
235
236
237 # [DeprecateAs]
238 def deprecate_as(member):
239     extended_attributes = member.extended_attributes
240     if 'DeprecateAs' not in extended_attributes:
241         return None
242     includes.add('core/frame/UseCounter.h')
243     return extended_attributes['DeprecateAs']
244
245
246 # [Exposed]
247 EXPOSED_EXECUTION_CONTEXT_METHOD = {
248     'DedicatedWorker': 'isDedicatedWorkerGlobalScope',
249     'ServiceWorker': 'isServiceWorkerGlobalScope',
250     'SharedWorker': 'isSharedWorkerGlobalScope',
251     'Window': 'isDocument',
252     'Worker': 'isWorkerGlobalScope',
253 }
254
255
256 def exposed(definition_or_member, interface):
257     exposure_set = extended_attribute_value_as_list(definition_or_member, 'Exposed')
258     if not exposure_set:
259         return None
260
261     interface_exposure_set = expanded_exposure_set_for_interface(interface)
262
263     # Methods must not be exposed to a broader scope than their interface.
264     if not set(exposure_set).issubset(interface_exposure_set):
265         raise ValueError('Interface members\' exposure sets must be a subset of the interface\'s.')
266
267     exposure_checks = []
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 to a valid exposure scope.')
272
273         exposure_checks.append('context->%s()' % EXPOSED_EXECUTION_CONTEXT_METHOD[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
287
288 # [GarbageCollected], [WillBeGarbageCollected]
289 def gc_type(definition):
290     extended_attributes = definition.extended_attributes
291     if 'GarbageCollected' in extended_attributes:
292         return 'GarbageCollectedObject'
293     elif 'WillBeGarbageCollected' in extended_attributes:
294         return 'WillBeGarbageCollectedObject'
295     return 'RefCountedObject'
296
297
298 # [ImplementedAs]
299 def cpp_name(definition_or_member):
300     extended_attributes = definition_or_member.extended_attributes
301     if 'ImplementedAs' not in extended_attributes:
302         return definition_or_member.name
303     return extended_attributes['ImplementedAs']
304
305
306 def cpp_name_or_partial(interface):
307     cpp_class_name = cpp_name(interface)
308     if interface.is_partial:
309         return ''.join([cpp_class_name, 'Partial'])
310     return cpp_class_name
311
312
313 # [MeasureAs]
314 def measure_as(definition_or_member):
315     extended_attributes = definition_or_member.extended_attributes
316     if 'MeasureAs' not in extended_attributes:
317         return None
318     includes.add('core/frame/UseCounter.h')
319     return extended_attributes['MeasureAs']
320
321
322 # [PerContextEnabled]
323 def per_context_enabled_function_name(definition_or_member):
324     extended_attributes = definition_or_member.extended_attributes
325     if 'PerContextEnabled' not in extended_attributes:
326         return None
327     feature_name = extended_attributes['PerContextEnabled']
328     return 'ContextFeatures::%sEnabled' % uncapitalize(feature_name)
329
330
331 # [RuntimeEnabled]
332 def runtime_enabled_function_name(definition_or_member):
333     """Returns the name of the RuntimeEnabledFeatures function.
334
335     The returned function checks if a method/attribute is enabled.
336     Given extended attribute RuntimeEnabled=FeatureName, return:
337         RuntimeEnabledFeatures::{featureName}Enabled
338     """
339     extended_attributes = definition_or_member.extended_attributes
340     if 'RuntimeEnabled' not in extended_attributes:
341         return None
342     feature_name = extended_attributes['RuntimeEnabled']
343     return 'RuntimeEnabledFeatures::%sEnabled' % uncapitalize(feature_name)