Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(124)

Side by Side Diff: Source/bindings/scripts/v8_attributes.py

Issue 17572008: WIP IDL compiler rewrite (Closed) Base URL: https://chromium.googlesource.com/chromium/blink@master
Patch Set: Branch: const + primitive type readonly attributes Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/bindings/scripts/idl_compiler.py ('k') | Source/bindings/scripts/v8_constructors.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 """Generate template values for attributes.
30
31 FIXME: rename "parameter/parameters":
32 "template parameters" is easily confused with "function parameters"
33 Also, "parameter*s*", not "parameter".
34 """
35
36 import v8_types
37 from v8_types import cpp_type, v8_type
38 from v8_utilities import generate_conditional_string, implemented_as_cpp_name, u ncapitalize
39 import v8_values
40
41 # WIP
42 import re
43
44 from code_generator_idl_reader import inherits_interface, implemented_as_from_im plemented_by
45 from v8_includes import *
46 from v8_types import *
47 from v8_utilities import capitalize, runtime_enable_function_name, strip_suffix
48 from v8_utilities import ACTIVITY_LOGGING_INCLUDES, get_call_with_parameter, get _custom_element_invocation_scope_parameter, get_feature_observation_parameter, g et_deprecation_notification_parameter, has_activity_logging
49 from v8_values import get_js_value_to_native_statement, get_native_to_js_value_s tatement, get_pass_owner_expression
50
51
52 def generate_attributes(interface):
53 def generate_attribute(attribute):
54 attribute_contents, attribute_includes = generate_attribute_and_includes (interface, attribute)
55 includes.update(attribute_includes)
56 return attribute_contents
57
58 includes = set()
59 contents = generate_attributes_common(interface)
60 contents['attributes'] = [generate_attribute(attribute) for attribute in int erface.attributes]
61 return contents, includes
62
63
64 def generate_attributes_common(interface):
65 attributes = interface.attributes
66 v8_class_name = v8_types.get_v8_class_name(interface)
67 return {
68 # Size 0 constant array is not allowed in VC++
69 # FIXME: rename Attrs to Attributes
70 'number_of_attributes': 'WTF_ARRAY_LENGTH(%sAttrs)' % v8_class_name if a ttributes else '0',
71 'attribute_templates': v8_class_name + 'Attrs' if attributes else '0',
72 }
73
74
75 def generate_attribute_and_includes(interface, attribute):
76 data_type = attribute.data_type
77 # FIXME: need to check should_keep_attribute_alive, but for now sufficient
78 # to check if primitive.
79 should_keep_attribute_alive = not v8_types.primitive_type(data_type)
80 # FIXME: eliminate should_keep_attribute_alive
81 if should_keep_attribute_alive:
82 return_js_value_statement = None # unused
83 includes = includes_for_type(data_type)
84 includes.add('bindings/v8/V8HiddenPropertyName.h')
85 else:
86 cpp_value = getter_expression(interface, attribute)
87 return_js_value_statement = v8_values.cpp_value_to_js_value_return(data_ type, cpp_value, callback_info='info')
88 includes = []
89 contents = {
90 'name': attribute.name,
91 'conditional_string': generate_conditional_string(attribute),
92 'cpp_method_name': implemented_as_cpp_name(attribute),
93 'cpp_type': cpp_type(data_type, pointer_type='RefPtr'),
94 'should_keep_attribute_alive': should_keep_attribute_alive,
95 'return_js_value_statement': return_js_value_statement,
96 'v8_type': v8_type(data_type),
97 }
98 return contents, includes
99
100
101 def getter_expression(interface, attribute):
102 # FIXME: very incomplete
103 return 'imp->%s()' % uncapitalize(attribute.name)
104
105
106 ################################################################################
107 # WIP
108 ################################################################################
109
110
111 def generate_attributes_wip(interface):
112 def generate_attribute(attribute):
113 attribute_contents, attribute_includes = generate_attribute_and_includes _wip(interface, attribute)
114 includes.extend(attribute_includes)
115 return attribute_contents
116
117 includes = []
118 contents = [generate_attribute(attribute) for attribute in interface.attribu tes]
119 return contents, includes
120
121
122 def generate_attribute_and_includes_wip(interface, attribute):
123 cpp_class_name = implemented_as_cpp_name(interface)
124 per_world_bindings = 'PerWorldBindings' in attribute.extended_attributes
125 for_main_world_suffixes = ['']
126 if per_world_bindings:
127 for_main_world_suffixes.append('ForMainWorld')
128
129 includes = []
130 # print
131 # print '#'*30
132 # print '[get_attribute_parameter] ', attribute.data_type, attribute.name
133
134 check_security_for_node = 'CheckSecurityForNode' in attribute.extended_attri butes
135 if check_security_for_node:
136 includes.append('bindings/v8/BindingSecurity.h')
137 if attribute.data_type == 'SerializedScriptValue':
138 includes.append('bindings/v8/SerializedScriptValue.h')
139
140 getter_activity_logging = set()
141 for for_main_world_suffix in for_main_world_suffixes:
142 if has_activity_logging(for_main_world_suffix, attribute.extended_attrib utes, 'Getter'):
143 getter_activity_logging.add(for_main_world_suffix)
144 includes += ACTIVITY_LOGGING_INCLUDES
145
146 custom_element_invocation_scope_parameter, custom_element_invocation_scope_i ncludes = get_custom_element_invocation_scope_parameter(attribute)
147 includes += custom_element_invocation_scope_includes
148 # print '[[]]', custom_element_invocation_scope_parameter
149
150 enable_function = runtime_enable_function_name(attribute)
151
152 replaceable = 'Replaceable' in attribute.extended_attributes
153 custom_getter = has_custom_getter(attribute)
154 custom_setter = has_custom_setter(attribute)
155 has_replaceable = not custom_setter and replaceable
156 has_normal_setter = (custom_setter or not has_replaceable) and not is_read_o nly(attribute)
157
158 should_keep_attribute_alive = get_should_keep_attribute_alive(interface, att ribute)
159 # print '[] should_keep_attribute_alive', should_keep_attribute_alive
160
161 native_type = ''
162 array_type = ''
163 if not custom_getter:
164 native_type = get_native_type(attribute.data_type, extended_attributes=a ttribute.extended_attributes)
165 # currently array_type is always False
166 array_type = get_array_type(native_type)
167 if should_keep_attribute_alive:
168 if array_type:
169 includes.append('V8%s.h' % array_type)
170 else:
171 includes += get_includes_for_type(attribute.data_type)
172 includes.append('bindings/v8/V8HiddenPropertyName.h')
173 if (setter_use_exception(attribute) and not custom_setter) or getter_use _exception(attribute):
174 includes.append('bindings/v8/ExceptionState.h')
175
176 batched_attribute, batched_attribute_includes = generate_batched_attribute(i nterface, attribute, ',')
177 includes += batched_attribute_includes
178
179 enabled_at_runtime = False
180 enabled_per_context = False
181 if interface.name == 'Window' and 'Unforgeable' in attribute.extended_attrib utes:
182 pass
183 elif 'EnabledPerContext' in attribute.extended_attributes:
184 enabled_per_context = True
185 elif 'EnabledAtRuntime' in attribute.extended_attributes:
186 enabled_at_runtime = True
187 else:
188 pass
189
190 if enabled_at_runtime:
191 batched_attribute, batched_attribute_includes = generate_batched_attribu te(interface, attribute, ';')
192 includes += batched_attribute_includes
193
194 compact_getter = 'Reflect' in attribute.extended_attributes and 'URL' not in attribute.extended_attributes and inherits_interface(interface, 'Node') and att ribute.data_type == 'DOMString'
195 compact_setter = 'Reflect' in attribute.extended_attributes and inherits_int erface(interface, 'Node') and attribute.data_type == 'DOMString'
196 compact_setter_namespace = ''
197 compact_setter_content_attribute_name = ''
198 if compact_setter:
199 compact_setter_content_attribute_name = attribute.name.lower()
200 if attribute.extended_attributes.get('Reflect'):
201 compact_setter_content_attribute_name = attribute.extended_attribute s.get('Reflect')
202 compact_setter_namespace = namespace_for_attribute_name(interface.name, compact_setter_content_attribute_name)
203 includes.append('%s.h' % compact_setter_namespace)
204
205 feature_observation_parameter, feature_observation_includes = get_feature_ob servation_parameter(interface)
206 includes += feature_observation_includes
207 deprecation_notification_parameter, deprecation_notification_includes = get_ deprecation_notification_parameter(attribute)
208 includes += deprecation_notification_includes
209
210 getter_function = ''
211 event_listener_setter_function_name = ''
212 event_listener_setter_function_name_not_inherits_node = ''
213 not_inherits_node = False
214 if attribute.data_type == 'EventListener':
215 # FIXME: Pass the main world ID for main-world-only getters.
216 includes.append('bindings/v8/V8AbstractEventListener.h')
217 includes.append('bindings/v8/V8EventListenerList.h')
218 getter_function = uncapitalize(attribute.name)
219 event_listener_setter_function_name = capitalize(attribute.name)
220 not_inherits_node = not inherits_interface(interface, 'Node')
221 if not_inherits_node:
222 event_listener_setter_function_name_not_inherits_node = implemented_ as_cpp_name(attribute)
223 event_listener_on_error = (interface.name == 'Window' or interface.name == 'WorkerGlobalScope') and attribute.name == 'onerror'
224 if event_listener_on_error:
225 includes.append('bindings/v8/V8ErrorHandler.h')
226
227 svg_animated_type = is_svg_animated_type(interface.name)
228 svg_type_needing_tear_off = get_svg_type_needing_tear_off(attribute.data_typ e)
229
230 ##################### Getter
231 getter_native_value_expression, getter_function_call_parameter, getter_inclu des = get_attribute_function_call_expression(interface, attribute)
232 includes += getter_includes
233 # print '[]', getter_native_value_expression
234
235 tear_off_and_not_list = svg_type_needing_tear_off and not interface.name.end swith('List')
236
237 wrapped_value = ''
238 return_js_value_statements = {}
239 assign_native_value_to_local_variable_statement = ''
240 if not custom_getter:
241 if (svg_animated_type or interface.name == 'SVGViewSpec') and svg_type_n eeding_tear_off:
242 includes.append('V8%s.h' % attribute.data_type)
243 elif tear_off_and_not_list:
244 includes.append('V8%s.h' % attribute.data_type)
245 includes.append('core/svg/properties/SVGPropertyTearOff.h')
246 if svg_type_with_writable_properties_needing_tear_off(attribute.data _type) and 'Immutable' not in attribute.extended_attributes:
247 getter = getter_native_value_expression
248 getter = getter.replace('imp->', '')
249 getter = getter.replace('\(\)', '')
250
251 update_method = '&%s::update%s' % (cpp_class_name, capitalize(ge tter))
252
253 self_is_tear_off_type = get_svg_type_needing_tear_off(interface. name)
254 if self_is_tear_off_type:
255 includes.append('core/svg/properties/SVGStaticPropertyWithPa rentTearOff.h')
256 svg_type_needing_tear_off = svg_type_needing_tear_off.replac e('SVGPropertyTearOff<', 'SVGStaticPropertyWithParentTearOff<%s, ' % cpp_class_n ame)
257 wrapped_value = 'WTF::getPtr(%s::create(wrapper, %s, %s))' % (svg_type_needing_tear_off, getter_native_value_expression, update_method)
258 else:
259 includes.append('core/svg/properties/SVGStaticPropertyTearOf f.h')
260 svg_type_needing_tear_off = svg_type_needing_tear_off.replac e('SVGPropertyTearOff<', 'SVGStaticPropertyTearOff<%s, ' % cpp_class_name)
261 wrapped_value = 'WTF::getPtr(%s::create(imp, %s, %s))' % (sv g_type_needing_tear_off, getter_native_value_expression, update_method)
262 elif 'SVGStaticListPropertyTearOff' in svg_type_needing_tear_off:
263 wrapped_value = 'WTF::getPtr(%s::create(imp, %s))' % (svg_type_n eeding_tear_off, getter_native_value_expression)
264 elif re.search('SVG(Point|PathSeg)List', svg_type_needing_tear_off):
265 wrapped_value = 'WTF::getPtr(%s)' % getter_native_value_expressi on
266 else:
267 wrapped_value = 'WTF::getPtr(%s::create(%s))' % (svg_type_needin g_tear_off, getter_native_value_expression)
268 elif attribute.data_type == 'SerializedScriptValue' and 'CachedAttribute ' in attribute.extended_attributes:
269 pass
270 elif attribute.data_type == 'EventListener':
271 pass
272 else:
273 original_getter_native_value_expression = getter_native_value_expres sion
274 # Fix amigious conversion problem, by casting to the base type first ($getterString returns a type that inherits from SVGAnimatedEnumeration, not th e base class directly).
275 if attribute.data_type == 'SVGAnimatedEnumeration':
276 getter_native_value_expression = 'static_pointer_cast<SVGAnimate dEnumeration>(%s)' % getter_native_value_expression
277
278 # print '[get_attribute_parameter] native_type', native_type
279 if attribute.is_nullable or getter_use_exception(attribute):
280 # used in local variable type
281 assign_native_value_to_local_variable_statement = '%s v = %s;' % (native_type, getter_native_value_expression)
282 getter_native_value_expression = get_pass_owner_expression(attri bute.data_type, 'v')
283
284 for for_main_world_suffix in for_main_world_suffixes:
285 if attribute.data_type != 'EventListener':
286 return_js_value_statement, native_to_js_value_includes = get _native_to_js_value_statement(attribute.data_type, attribute.extended_attributes , getter_native_value_expression, creation_context='info.Holder()', isolate='inf o.GetIsolate()', callback_info='info', script_wrappable='imp', for_main_world_su ffix=for_main_world_suffix, used_as_return_value=True)
287 return_js_value_statements[for_main_world_suffix] = return_j s_value_statement
288 if should_keep_attribute_alive:
289 assign_native_value_to_local_variable_statement = '%s v = %s;' % (native_type, original_getter_native_value_expression)
290 getter_native_value_expression = original_getter_native_ value_expression
291 else:
292 includes += native_to_js_value_includes
293
294 ##################### Setter
295 # native to JS (getter)
296 assign_js_value_to_local_variable_statement = ''
297 setter_native_value_expression = ''
298 set_value_statement = ''
299 setter_activity_logging = set()
300 setter_function_call_parameter = {}
301 if has_normal_setter:
302 for for_main_world_suffix in for_main_world_suffixes:
303 if has_activity_logging(for_main_world_suffix, attribute.extended_at tributes, 'Setter'):
304 setter_activity_logging.add(for_main_world_suffix)
305 includes += ACTIVITY_LOGGING_INCLUDES
306
307 # JS to native (setter)
308 if attribute.data_type != 'EventListener':
309 assign_js_value_to_local_variable_statement, js_value_to_native_incl udes = get_js_value_to_native_statement(attribute.data_type, attribute.extended_ attributes, 'value', 'v', 'info.GetIsolate()')
310 includes += js_value_to_native_includes
311
312 setter_native_value_expression = 'v'
313 if is_ref_ptr_type(attribute.data_type) and not get_array_type(attribute .data_type):
314 setter_native_value_expression = 'WTF::getPtr(%s)' % setter_native_v alue_expression
315
316 # set native value statement
317 setter_native_value_expression, setter_function_call_parameter, setter_i ncludes = get_attribute_function_call_expression(interface, attribute, is_setter =True, setter_native_value_expression=setter_native_value_expression)
318 includes += setter_includes
319
320 set_value_statement = '%s;' % setter_native_value_expression
321 # print '[attribute] set_value_statement', set_value_statement
322
323 is_normal = False
324 if interface.name == 'Window' and 'Unforgeable' in attribute.extended_attrib utes:
325 pass
326 elif 'EnabledAtRuntime' in attribute.extended_attributes or 'EnabledPerConte xt' in attribute.extended_attributes:
327 pass
328 else:
329 is_normal = True
330
331 parameter = {
332 'name': attribute.name,
333 'type': attribute.data_type,
334 'is_static': attribute.is_static,
335 'is_normal': is_normal,
336 'native_type': native_type,
337 'svg_animated_type': svg_animated_type,
338 'svg_type_needing_tear_off': svg_type_needing_tear_off,
339 'tear_off_and_not_list': tear_off_and_not_list,
340 'check_security_for_node': check_security_for_node,
341 'enable_function': enable_function,
342
343 # EventListner hack
344 'getter_function': getter_function,
345 'event_listener_setter_function_name': event_listener_setter_function_na me,
346 'event_listener_setter_function_name_not_inherits_node': event_listener_ setter_function_name_not_inherits_node,
347 'not_inherits_node': not_inherits_node,
348
349 'getter_native_value_expression': getter_native_value_expression,
350 'setter_native_value_expression': setter_native_value_expression,
351 'return_js_value_statements': return_js_value_statements,
352 'set_value_statement': set_value_statement,
353 'conditional_string': generate_conditional_string(attribute),
354 'batched_attribute': batched_attribute,
355 'getter_use_exceptions': getter_use_exception(attribute),
356 'setter_use_exceptions': setter_use_exception(attribute),
357 'is_nullable': attribute.is_nullable,
358 'assign_native_value_to_local_variable_statement': assign_native_value_t o_local_variable_statement,
359 'assign_js_value_to_local_variable_statement': assign_js_value_to_local_ variable_statement,
360 'has_replaceable': has_replaceable,
361 'has_normal_setter': has_normal_setter,
362 'has_custom_getter': custom_getter,
363 'has_custom_setter': custom_setter,
364 'per_world_bindings': per_world_bindings,
365 'for_main_world_suffixes': for_main_world_suffixes,
366 'should_keep_attribute_alive': should_keep_attribute_alive,
367 'array_type': array_type,
368 'getter_activity_logging': getter_activity_logging,
369 'setter_activity_logging': setter_activity_logging,
370 'enabled_at_runtime': enabled_at_runtime,
371 'enabled_per_context': enabled_per_context,
372 'compact_getter': compact_getter,
373 'compact_setter': compact_setter,
374 'compact_setter_namespace': compact_setter_namespace,
375 'compact_setter_content_attribute_name': compact_setter_content_attribut e_name,
376 'cached_attribute': 'CachedAttribute' in attribute.extended_attributes,
377 'wrapped_value': wrapped_value,
378 'cpp_name': implemented_as_cpp_name(attribute),
379 'initialized_by_event_constructor': 'InitializedByEventConstructor' in a ttribute.extended_attributes,
380 'setter': 'setSerialized' + capitalize(attribute.name),
381 }
382 parameter.update(feature_observation_parameter)
383 parameter.update(deprecation_notification_parameter)
384 parameter.update(custom_element_invocation_scope_parameter)
385 parameter.update(getter_function_call_parameter)
386 parameter.update(setter_function_call_parameter)
387 return parameter, includes
388
389
390 def generate_batched_attribute(interface, attribute, delimiter, indent=''):
391 # GenerateSingleBatchedAttribute in perl
392 cpp_class_name = implemented_as_cpp_name(interface)
393 v8_class_name = get_v8_class_name(interface)
394 is_constructor = attribute.data_type.endswith('Constructor')
395 # print '[--]', attribute.name, attribute.data_type, is_constructor
396 includes = []
397
398 access_control = 'v8::DEFAULT'
399 if attribute.extended_attributes.get('DoNotCheckSecurityOnGetter'):
400 access_control = 'v8::ALL_CAN_READ'
401 elif attribute.extended_attributes.get('DoNotCheckSecurityOnSetter'):
402 access_control = 'v8::ALL_CAN_WRITE'
403 elif attribute.extended_attributes.get('DoNotCheckSecurity'):
404 access_control = 'v8::ALL_CAN_READ'
405 if not is_read_only(attribute):
406 access_control += ' | v8::ALL_CAN_WRITE'
407 if attribute.extended_attributes.get('Unforgeable'):
408 access_control += ' | v8::PROHIBITS_OVERWRITING'
409 access_control = 'static_cast<v8::AccessControl>(%s)' % access_control
410
411 prop_attr = 'v8::None'
412 # Check attributes.
413 # As per Web IDL specification, constructor properties on the ECMAScript glo bal object should be
414 # configurable and should not be enumerable.
415 if 'NotEnumerable' in attribute.extended_attributes or is_constructor:
416 prop_attr += ' | v8::DontEnum'
417 if 'Unforgeable' in attribute.extended_attributes and not is_constructor:
418 prop_attr += ' | v8::DontDelete'
419
420 on_proto = '0 /* on instance */'
421 if is_constructor:
422 constructor_type = strip_suffix(attribute.data_type, 'Constructor')
423 # $constructorType ~= /Constructor$/ indicates that it is NamedConstruct or.
424 # We do not generate the header file for NamedConstructor of class XXXX,
425 # since we generate the NamedConstructor declaration into the header fil e of class XXXX.
426 # FIXME: We just stripped the 'Constructor' suffix!
427 if not constructor_type.endswith('Constructor') or attribute.extended_at tributes.get('CustomConstructor'):
428 includes.append('V8%s.h' % constructor_type)
429 getter = '%sV8Internal::%sConstructorGetter' % (cpp_class_name, cpp_clas s_name)
430 setter = '%sV8Internal::%sReplaceableAttrSetterCallback' % (cpp_class_na me, cpp_class_name)
431 getter_for_main_world = '0'
432 setter_for_main_world = '0'
433 data = '&V8${constructorType}::info'
434 else:
435 # Default Getter and Setter
436 getter = '%sV8Internal::%sAttrGetterCallback' % (cpp_class_name, attribu te.name)
437 setter = '%sV8Internal::%sAttrSetterCallback' % (cpp_class_name, attribu te.name)
438 getter_for_main_world = getter + 'ForMainWorld'
439 setter_for_main_world = setter + 'ForMainWorld'
440 data = '0 /* no data */'
441 if not has_custom_setter(attribute) and attribute.extended_attributes.ge t('Replaceable'):
442 setter = '%sV8Internal::%sReplaceableAttrSetterCallback' % (cpp_clas s_name, cpp_class_name)
443 setter_for_main_world = '0'
444 # Read only attributes
445 if is_read_only(attribute):
446 setter = '0'
447 setter_for_main_world = '0'
448 if 'PerWorldBindings' not in attribute.extended_attributes:
449 getter_for_main_world = '0'
450 setter_for_main_world = '0'
451
452 # An accessor can be installed on the proto
453 if attribute.extended_attributes.get('OnProto'):
454 on_proto = '1 /* on proto */'
455
456 code = (
457 '{"%s", %s, %s, %s, %s, %s, %s, static_cast<v8::PropertyAttribute>(%s), %s}%s' %
458 (attribute.name, getter, setter, getter_for_main_world, setter_for_main_ world, data, access_control, prop_attr, on_proto, delimiter))
459 return code, includes
460
461
462 # Auxiliary functions
463
464
465 def get_should_keep_attribute_alive(interface, attribute):
466 return (
467 'KeepAttributeAliveForGC' in attribute.extended_attributes or
468 # Basically, for readonly or replaceable attributes, we have to
469 # guarantee that JS wrappers don't get garbage-collected prematually
470 # when their lifetime is strongly tied to their owner.
471 ((is_wrapper_type(attribute.data_type) and
472 (is_read_only(attribute) or
473 'Replaceable' in attribute.extended_attributes)) and
474 # However, there are a couple of exceptions.
475 not(
476 # Node lifetime is managed by object grouping.
477 inherits_interface(interface, 'Node') or
478 is_dom_node_type(attribute.data_type) or
479 # To avoid adding a reference to itself.
480 # FIXME: Introduce [DoNotKeepAttributeAliveForGC] and remove
481 # this hack of depending on the attribute name.
482 attribute.name == 'self' or
483 # FIXME: Remove these hard-coded hacks.
484 attribute.data_type in ['EventTarget', 'SerializedScriptValue', 'Win dow'] or
485 'SVG' in attribute.data_type or
486 'HTML' in attribute.data_type)))
487
488
489 def get_attribute_function_call_expression(interface, attribute, is_setter=False , setter_native_value_expression=None):
490 """
491 @return function_call_expression, includes
492 """
493 # GetterExpression / SetterExpression in perl
494 includes = []
495 arguments = []
496 interface_name = interface.name
497 cpp_class_name = implemented_as_cpp_name(interface)
498 content_attribute_name, additional_includes = get_content_attribute_name(int erface_name, attribute)
499 includes += additional_includes
500
501 function_name = ''
502 if is_setter:
503 if content_attribute_name:
504 if attribute.data_type == 'boolean':
505 function_name = 'setBooleanAttribute'
506 elif attribute.data_type == 'long':
507 function_name = 'setIntegralAttribute'
508 elif attribute.data_type == 'unsigned long':
509 function_name = 'setUnsignedIntegralAttribute'
510 else:
511 function_name = 'setAttribute'
512 else:
513 function_name = 'set' + capitalize(implemented_as_cpp_name(attribute ))
514 else:
515 if content_attribute_name:
516 if 'URL' in attribute.extended_attributes:
517 function_name = 'getURLAttribute'
518 elif attribute.data_type == 'boolean':
519 function_name = 'fastHasAttribute'
520 elif attribute.data_type == 'long':
521 function_name = 'getIntegralAttribute'
522 elif attribute.data_type == 'unsigned long':
523 function_name = 'getUnsignedIntegralAttribute'
524 elif content_attribute_name == 'WebCore::HTMLNames::idAttr':
525 function_name = 'getIdAttribute'
526 content_attribute_name = ''
527 elif content_attribute_name == 'WebCore::HTMLNames::nameAttr':
528 function_name = 'getNameAttribute'
529 content_attribute_name = ''
530 elif content_attribute_name == 'WebCore::HTMLNames::classAttr':
531 function_name = 'getClassAttribute'
532 content_attribute_name = ''
533 elif is_svg_animated_type(attribute.data_type):
534 # We cannot use fast attributes for animated SVG types.
535 function_name = 'getAttribute'
536 else:
537 function_name = 'fastGetAttribute'
538 else:
539 function_name = uncapitalize(implemented_as_cpp_name(attribute))
540 # print '[[]]', function_name
541 if content_attribute_name:
542 arguments.append(content_attribute_name)
543
544 implemented_by = attribute.extended_attributes.get('ImplementedBy')
545 if implemented_by:
546 implemented_by_cpp_name = implemented_as_from_implemented_by(implemented _by)
547 includes += header_files_for_interface(implemented_by, implemented_by_cp p_name)
548 if not attribute.is_static:
549 arguments = ['imp'] + arguments
550 function_name = '%s::%s' % (implemented_by_cpp_name, function_name)
551 elif attribute.is_static:
552 function_name = '%s::%s' % (cpp_class_name, function_name)
553 else:
554 function_name = 'imp->%s' % function_name
555
556 if is_setter:
557 arguments.append(setter_native_value_expression)
558 if setter_use_exception(attribute):
559 arguments.append('es')
560 call_with = attribute.extended_attributes.get('SetterCallWith') or attri bute.extended_attributes.get('CallWith')
561 else:
562 if attribute.is_nullable:
563 arguments.append('isNull')
564 if getter_use_exception(attribute):
565 arguments.append('es')
566 call_with = attribute.extended_attributes.get('CallWith')
567
568 call_with_arguments, call_with_parameter, call_with_includes = get_call_with _parameter(call_with)
569 includes += call_with_includes
570 arguments = call_with_arguments + arguments
571
572 function_call_expression = '%s(%s)' % (function_name, ', '.join(arguments))
573 return function_call_expression, call_with_parameter, includes
574
575
576 def get_custom_element_invocation_scope_parameter(interface_or_attribute_or_func tion):
577 # print '[[]]', interface_or_attribute_or_function.extended_attributes
578 custom_element_invocation_scope = has_extended_attribute(interface_or_attrib ute_or_function, ['DeliverCustomElementCallbacks', 'Reflect'])
579 parameter = {
580 'custom_element_invocation_scope': custom_element_invocation_scope,
581 }
582 if custom_element_invocation_scope:
583 includes = ['core/dom/CustomElementCallbackDispatcher.h']
584 else:
585 includes = []
586 return parameter, includes
587
588
589 def has_extended_attribute(item, extended_attribute_list):
590 # FIXME: useful function, use widely
591 return any([extended_attribute in item.extended_attributes
592 for extended_attribute in extended_attribute_list])
593
594
595 def getter_use_exception(attribute):
596 return has_extended_attribute(attribute, ['GetterRaisesException', 'RaisesEx ception'])
597
598
599 def setter_use_exception(attribute):
600 return has_extended_attribute(attribute, ['SetterRaisesException', 'RaisesEx ception'])
601
602
603 def namespace_for_attribute_name(interface_name, attribute_name):
604 if (interface_name.startswith('SVG') and
605 attribute_name not in SVG_ATTRIBUTES_IN_HTML):
606 return 'SVGNames'
607 return 'HTMLNames'
608
609
610 def get_content_attribute_name(interface_name, attribute):
611 if 'Reflect' not in attribute.extended_attributes:
612 return None, []
613 default_content_attribute_name = implemented_as_cpp_name(attribute).lower()
614 content_attribute_name = attribute.extended_attributes['Reflect'] or default _content_attribute_name
615 namespace = namespace_for_attribute_name(interface_name, content_attribute_n ame)
616 scoped_name = 'WebCore::%s::%sAttr' % (namespace, content_attribute_name)
617 includes = [namespace + '.h']
618 return scoped_name, includes
OLDNEW
« no previous file with comments | « Source/bindings/scripts/idl_compiler.py ('k') | Source/bindings/scripts/v8_constructors.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698