• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
31Extends IdlType and IdlUnion type with |enum_validation_expression| property.
32
33Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
34"""
35
36import re
37
38from idl_types import IdlType, IdlUnionType
39import idl_types
40from v8_globals import includes
41import v8_types
42
43ACRONYMS = [
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
61def extended_attribute_value_contains(extended_attribute_value, value):
62    return (extended_attribute_value and
63            value in re.split('[|&]', extended_attribute_value))
64
65
66def has_extended_attribute(definition_or_member, extended_attribute_list):
67    return any(extended_attribute in definition_or_member.extended_attributes
68               for extended_attribute in extended_attribute_list)
69
70
71def has_extended_attribute_value(definition_or_member, name, value):
72    extended_attributes = definition_or_member.extended_attributes
73    return (name in extended_attributes and
74            extended_attribute_value_contains(extended_attributes[name], value))
75
76
77################################################################################
78# String handling
79################################################################################
80
81def capitalize(name):
82    """Capitalize first letter or initial acronym (used in setter names)."""
83    for acronym in ACRONYMS:
84        if name.startswith(acronym.lower()):
85            return name.replace(acronym.lower(), acronym)
86    return name[0].upper() + name[1:]
87
88
89def strip_suffix(string, suffix):
90    if not suffix or not string.endswith(suffix):
91        return string
92    return string[:-len(suffix)]
93
94
95def uncapitalize(name):
96    """Uncapitalizes first letter or initial acronym (used in method names).
97
98    E.g., 'SetURL' becomes 'setURL', but 'URLFoo' becomes 'urlFoo'.
99    """
100    for acronym in ACRONYMS:
101        if name.startswith(acronym):
102            return name.replace(acronym, acronym.lower())
103    return name[0].lower() + name[1:]
104
105
106################################################################################
107# C++
108################################################################################
109
110def enum_validation_expression(idl_type):
111    # FIXME: Add IdlEnumType, move property to derived type, and remove this check
112    if not idl_type.is_enum:
113        return None
114    return ' || '.join(['string == "%s"' % enum_value
115                        for enum_value in idl_type.enum_values])
116IdlType.enum_validation_expression = property(enum_validation_expression)
117
118
119def scoped_name(interface, definition, base_name):
120    # partial interfaces are implemented as separate classes, with their members
121    # implemented as static member functions
122    partial_interface_implemented_as = definition.extended_attributes.get('PartialInterfaceImplementedAs')
123    if partial_interface_implemented_as:
124        return '%s::%s' % (partial_interface_implemented_as, base_name)
125    if (definition.is_static or
126        definition.name in ('Constructor', 'NamedConstructor')):
127        return '%s::%s' % (cpp_name(interface), base_name)
128    return 'impl->%s' % base_name
129
130
131def v8_class_name(interface):
132    return v8_types.v8_type(interface.name)
133
134
135################################################################################
136# Specific extended attributes
137################################################################################
138
139# [ActivityLogging]
140def activity_logging_world_list(member, access_type=''):
141    """Returns a set of world suffixes for which a definition member has activity logging, for specified access type.
142
143    access_type can be 'Getter' or 'Setter' if only checking getting or setting.
144    """
145    extended_attributes = member.extended_attributes
146    if 'LogActivity' not in extended_attributes:
147        return set()
148    log_activity = extended_attributes['LogActivity']
149    if log_activity and not log_activity.startswith(access_type):
150        return set()
151
152    includes.add('bindings/v8/V8DOMActivityLogger.h')
153    if 'LogAllWorlds' in extended_attributes:
154        return set(['', 'ForMainWorld'])
155    return set([''])  # At minimum, include isolated worlds.
156
157
158# [ActivityLogging]
159def activity_logging_world_check(member):
160    """Returns if an isolated world check is required when generating activity
161    logging code.
162
163    The check is required when there is no per-world binding code and logging is
164    required only for isolated world.
165    """
166    extended_attributes = member.extended_attributes
167    if 'LogActivity' not in extended_attributes:
168        return False
169    if ('PerWorldBindings' not in extended_attributes and
170        'LogAllWorlds' not in extended_attributes):
171        return True
172    return False
173
174
175# [CallWith]
176CALL_WITH_ARGUMENTS = {
177    'ScriptState': 'scriptState',
178    'ExecutionContext': 'executionContext',
179    'ScriptArguments': 'scriptArguments.release()',
180    'ActiveWindow': 'callingDOMWindow(info.GetIsolate())',
181    'FirstWindow': 'enteredDOMWindow(info.GetIsolate())',
182    'Document': 'document',
183}
184# List because key order matters, as we want arguments in deterministic order
185CALL_WITH_VALUES = [
186    'ScriptState',
187    'ExecutionContext',
188    'ScriptArguments',
189    'ActiveWindow',
190    'FirstWindow',
191    'Document',
192]
193
194
195def call_with_arguments(call_with_values):
196    if not call_with_values:
197        return []
198    return [CALL_WITH_ARGUMENTS[value]
199            for value in CALL_WITH_VALUES
200            if extended_attribute_value_contains(call_with_values, value)]
201
202
203# [Conditional]
204def conditional_string(definition_or_member):
205    extended_attributes = definition_or_member.extended_attributes
206    if 'Conditional' not in extended_attributes:
207        return None
208    conditional = extended_attributes['Conditional']
209    for operator in '&|':
210        if operator in conditional:
211            conditions = conditional.split(operator)
212            operator_separator = ' %s%s ' % (operator, operator)
213            return operator_separator.join('ENABLE(%s)' % expression for expression in sorted(conditions))
214    return 'ENABLE(%s)' % conditional
215
216
217# [DeprecateAs]
218def deprecate_as(member):
219    extended_attributes = member.extended_attributes
220    if 'DeprecateAs' not in extended_attributes:
221        return None
222    includes.add('core/frame/UseCounter.h')
223    return extended_attributes['DeprecateAs']
224
225
226# [GarbageCollected], [WillBeGarbageCollected]
227def gc_type(definition):
228    extended_attributes = definition.extended_attributes
229    if 'GarbageCollected' in extended_attributes:
230        return 'GarbageCollectedObject'
231    elif 'WillBeGarbageCollected' in extended_attributes:
232        return 'WillBeGarbageCollectedObject'
233    return 'RefCountedObject'
234
235
236# [ImplementedAs]
237def cpp_name(definition_or_member):
238    extended_attributes = definition_or_member.extended_attributes
239    if 'ImplementedAs' not in extended_attributes:
240        return definition_or_member.name
241    return extended_attributes['ImplementedAs']
242
243
244# [MeasureAs]
245def measure_as(definition_or_member):
246    extended_attributes = definition_or_member.extended_attributes
247    if 'MeasureAs' not in extended_attributes:
248        return None
249    includes.add('core/frame/UseCounter.h')
250    return extended_attributes['MeasureAs']
251
252
253# [PerContextEnabled]
254def per_context_enabled_function_name(definition_or_member):
255    extended_attributes = definition_or_member.extended_attributes
256    if 'PerContextEnabled' not in extended_attributes:
257        return None
258    feature_name = extended_attributes['PerContextEnabled']
259    return 'ContextFeatures::%sEnabled' % uncapitalize(feature_name)
260
261
262# [RuntimeEnabled]
263def runtime_enabled_function_name(definition_or_member):
264    """Returns the name of the RuntimeEnabledFeatures function.
265
266    The returned function checks if a method/attribute is enabled.
267    Given extended attribute RuntimeEnabled=FeatureName, return:
268        RuntimeEnabledFeatures::{featureName}Enabled
269    """
270    extended_attributes = definition_or_member.extended_attributes
271    if 'RuntimeEnabled' not in extended_attributes:
272        return None
273    feature_name = extended_attributes['RuntimeEnabled']
274    return 'RuntimeEnabledFeatures::%sEnabled' % uncapitalize(feature_name)
275