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

Side by Side Diff: Source/bindings/scripts/v8_types.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
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 import re
30
31 # WIP
32 import idl_definitions # for UnionType
33 from code_generator_idl_reader import implemented_as_cpp_name_from_idl_type, is_ callback_interface_base
34 from v8_utilities import uncapitalize # for non-type function?
35
36 CPP_TYPE_SAME_AS_IDL_TYPE = set([
37 'double',
38 'float',
39 'int', # FIXME: int is not an IDL type
40 'long long',
41 'unsigned long long',
42 ])
43 CPP_INT_TYPE = set([
44 'byte',
45 'long',
46 'short',
47 ])
48 CPP_UNSIGNED_TYPE = set([
49 'octet',
50 'unsigned int',
51 'unsigned long',
52 'unsigned short',
53 ])
54 CPP_TYPE_SPECIAL_CONVERSION_RULES = {
55 'boolean': 'bool',
56 'DOMString': 'const String&',
57 }
58 PRIMITIVE_TYPES = set([
59 # http://www.w3.org/TR/WebIDL/#dfn-primitive-type
60 'boolean',
61 'float',
62 # unrestricted float is not supported
63 'double',
64 # unrestricted double is not supported
65 # integer types
66 # http://www.w3.org/TR/WebIDL/#dfn-integer-type
67 'byte',
68 'octet',
69 'short',
70 'unsigned short',
71 # int and unsigned are not IDL types
72 'long',
73 'unsigned long',
74 'long long',
75 'unsigned long long',
76 # Blink-specific additions
77 'Date',
78 'void',
79 ])
80
81
82 def primitive_type(data_type):
83 return data_type in PRIMITIVE_TYPES
84
85
86 def get_sequence_type(data_type):
87 matched = re.match(r'sequence<([\w\d_\s]+)>', data_type)
88 return matched and matched.group(1)
89
90
91 def get_array_type(data_type):
92 matched = re.match(r'([\w\d_\s]+)\[\]', data_type)
93 return matched and matched.group(1)
94
95
96 def get_array_or_sequence_type(data_type):
97 return get_array_type(data_type) or get_sequence_type(data_type)
98
99
100 def cpp_type(data_type, pointer_type=None):
101 """Returns the C++ type corresponding to the IDL type.
102
103 Args:
104 pointer_type:
105 'raw': return raw pointer form (e.g. Foo*)
106 'RefPtr': return RefPtr form (e.g. RefPtr<Foo>)
107 'PassRefPtr': return PassRefPtr form (e.g. RefPtr<Foo>)
108 """
109 if data_type in CPP_TYPE_SAME_AS_IDL_TYPE:
110 return data_type
111 if data_type in CPP_INT_TYPE:
112 return 'int'
113 if data_type in CPP_UNSIGNED_TYPE:
114 return 'unsigned'
115 if data_type in CPP_TYPE_SPECIAL_CONVERSION_RULES:
116 return CPP_TYPE_SPECIAL_CONVERSION_RULES[data_type]
117 array_or_sequence_type = get_array_or_sequence_type(data_type)
118 if array_or_sequence_type:
119 # FIXME: const?
120 # return 'const Vector<%s >&' % cpp_type(array_or_sequence_type, 'RefPtr ')
121 return 'Vector<%s >' % cpp_type(array_or_sequence_type, 'RefPtr')
122 if pointer_type == 'raw':
123 return data_type + '*'
124 if pointer_type in ['RefPtr', 'PassRefPtr']:
125 return '%s<%s>' % (pointer_type, data_type)
126 raise Exception('Unrecognized pointer type: "%s"' % pointer_type)
127
128
129 def v8_type(data_type):
130 return 'V8' + data_type
131
132
133 def get_v8_class_name(interface):
134 return v8_type(interface.name)
135
136
137 ################################################################################
138 # WIP
139 ################################################################################
140
141 # name -> values
142 enum_types = {}
143 callback_function_types = set()
144
145 NON_WRAPPER_TYPES = set([
146 'CompareHow',
147 'DOMTimeStamp',
148 'Dictionary',
149 'EventListener',
150 'EventHandler',
151 'MediaQueryListListener',
152 'NodeFilter',
153 'SerializedScriptValue',
154 'any',
155 ])
156 DOM_NODE_TYPES = set([
157 'Attr',
158 'CDATASection',
159 'CharacterData',
160 'Comment',
161 'Document',
162 'DocumentFragment',
163 'DocumentType',
164 'Element',
165 'Entity',
166 'HTMLDocument',
167 'Node',
168 'Notation',
169 'ProcessingInstruction',
170 'ShadowRoot',
171 'SVGDocument',
172 'Text',
173 'TestNode',
174 ])
175 SVG_ATTRIBUTES_IN_HTML = set([
176 'class',
177 'id',
178 'onabort',
179 'onclick',
180 'onerror',
181 'onload',
182 'onmousedown',
183 'onmousemove',
184 'onmouseout',
185 'onmouseover',
186 'onmouseup',
187 'onresize',
188 'onscroll',
189 'onunload',
190 ])
191
192 # IDL type: [element's C++ type, V8 type]
193 TYPED_ARRAYS = {
194 'ArrayBuffer': [],
195 'ArrayBufferView': [],
196 'Uint8Array': ['unsigned char', 'v8::kExternalUnsignedByteArray'],
197 'Uint8ClampedArray': ['unsigned char', 'v8::kExternalPixelArray'],
198 'Uint16Array': ['unsigned short', 'v8::kExternalUnsignedShortArray'],
199 'Uint32Array': ['unsigned int', 'v8::kExternalUnsignedIntArray'],
200 'Int8Array': ['signed char', 'v8::kExternalByteArray'],
201 'Int16Array': ['short', 'v8::kExternalShortArray'],
202 'Int32Array': ['int', 'v8::kExternalIntArray'],
203 'Float32Array': ['float', 'v8::kExternalFloatArray'],
204 'Float64Array': ['double', 'v8::kExternalDoubleArray'],
205 }
206
207 SVG_TYPE_NEEDING_TEAR_OFF_DICT = {
208 'SVGAngle': 'SVGPropertyTearOff<SVGAngle>',
209 'SVGLength': 'SVGPropertyTearOff<SVGLength>',
210 'SVGLengthList': 'SVGListPropertyTearOff<SVGLengthList>',
211 'SVGMatrix': 'SVGPropertyTearOff<SVGMatrix>',
212 'SVGNumber': 'SVGPropertyTearOff<SVGNumber>',
213 'SVGNumberList': 'SVGListPropertyTearOff<SVGNumberList>',
214 'SVGPathSegList': 'SVGPathSegListPropertyTearOff',
215 'SVGPoint': 'SVGPropertyTearOff<SVGPoint>',
216 'SVGPointList': 'SVGListPropertyTearOff<SVGPointList>',
217 'SVGPreserveAspectRatio': 'SVGPropertyTearOff<SVGPreserveAspectRatio>',
218 'SVGRect': 'SVGPropertyTearOff<SVGRect>',
219 'SVGStringList': 'SVGStaticListPropertyTearOff<SVGStringList>',
220 'SVGTransform': 'SVGPropertyTearOff<SVGTransform>',
221 'SVGTransformList': 'SVGTransformListPropertyTearOff',
222 }
223
224
225 def is_wrapper_type(data_type):
226 return not(
227 is_union_type(data_type) or
228 get_array_type(data_type) or
229 get_sequence_type(data_type) or
230 is_callback_function_type(data_type) or
231 is_enum_type(data_type) or
232 is_primitive_type(data_type) or
233 data_type == 'DOMString' or
234 # FIXME: SVGPropertyTearOff<SVGAngle> -> False. is this OK?
235 'SVG' in data_type or
236 data_type in NON_WRAPPER_TYPES)
237
238
239 def is_callback_interface_etc(data_type):
240 return (data_type != 'ArrayBuffer' and
241 is_wrapper_type(data_type) and
242 is_callback_interface_base(data_type))
243
244
245 # TODO: GetNativeTypeOfTypedArray
246
247
248 def is_typed_array_type(data_type):
249 return data_type in TYPED_ARRAYS
250
251
252 def is_ref_ptr_type(data_type):
253 return not(
254 is_union_type(data_type) or
255 data_type in ['any', 'DOMString'] or
256 is_primitive_type(data_type) or
257 get_array_type(data_type) or
258 get_sequence_type(data_type) or
259 is_callback_function_type(data_type) or
260 is_enum_type(data_type))
261
262
263 def is_primitive_type(data_type):
264 return data_type in PRIMITIVE_TYPES
265
266
267 def is_enum_type(data_type):
268 return data_type in enum_types
269
270
271 def is_callback_function_type(data_type):
272 return data_type in callback_function_types
273
274
275 def is_dom_node_type(data_type):
276 return (data_type in DOM_NODE_TYPES or
277 (data_type.startswith(('HTML', 'SVG')) and data_type.endswith('Eleme nt')))
278
279
280 def is_union_type(data_type):
281 return isinstance(data_type, idl_definitions.IdlUnionType)
282
283
284 def skip_include_header(data_type):
285 return (is_primitive_type(data_type) or
286 is_enum_type(data_type) or
287 is_callback_function_type(data_type) or
288 data_type == 'DOMString')
289
290
291 ################################################################################
292 # SVG
293 ################################################################################
294
295
296 def is_svg_animated_type(data_type):
297 return data_type.startswith('SVGAnimated')
298
299
300 def get_svg_type_needing_tear_off(data_type):
301 return SVG_TYPE_NEEDING_TEAR_OFF_DICT.get(data_type, '')
302
303
304 def svg_type_with_writable_properties_needing_tear_off(data_type):
305 return data_type in ['SVGPoint', 'SVGMatrix']
306
307
308 def get_svg_wrapped_type_needing_tear_off(data_type):
309 svg_type_needing_tear_off = get_svg_type_needing_tear_off(data_type)
310 if not svg_type_needing_tear_off:
311 return ''
312
313 for name in ['SVGPropertyTearOff<', 'SVGListPropertyTearOff<', 'SVGStaticLis tPropertyTearOff<', 'SVGTransformListPropertyTearOff<']:
314 svg_type_needing_tear_off = svg_type_needing_tear_off.replace(name, '')
315
316 svg_type_needing_tear_off = svg_type_needing_tear_off.replace('>', '')
317 return svg_type_needing_tear_off
318
319
320 def get_svg_property_types(cpp_type):
321 header_includes = []
322 cpp_includes = []
323 svg_property_type = ''
324 svg_list_property_type = ''
325 svg_native_type = ''
326 # print '[get_svg_property_types] svg_native_type', cpp_type
327
328 if not re.search('SVG', cpp_type):
329 return '', '', '', [], []
330
331 svg_native_type = get_svg_type_needing_tear_off(cpp_type)
332 # print '[svg_native_type]', svg_native_type
333 if not svg_native_type:
334 return '', '', '', [], []
335
336 # Append space to avoid compilation errors when using PassRefPtr<$svgNativeT ype>
337 svg_native_type += ' '
338
339 svg_wrapped_native_type = get_svg_wrapped_type_needing_tear_off(cpp_type)
340 # print '[svg_wrapped_native_type]', svg_wrapped_native_type
341
342 if 'SVGPropertyTearOff' in svg_native_type:
343 svg_property_type = svg_wrapped_native_type
344 header_includes.append('core/svg/properties/SVGAnimatedPropertyTearOff.h ')
345 elif 'SVGListPropertyTearOff' in svg_native_type or 'SVGStaticListPropertyTe arOff' in svg_native_type or 'SVGTransformListPropertyTearOff' in svg_native_typ e:
346 svg_list_property_type = svg_wrapped_native_type
347 header_includes.append('core/svg/properties/SVGAnimatedListPropertyTearO ff.h')
348 elif 'SVGPathSegListPropertyTearOff' in svg_native_type:
349 svg_list_property_type = svg_wrapped_native_type
350 header_includes.append('core/svg/properties/SVGPathSegListPropertyTearOf f.h')
351
352 return svg_property_type, svg_list_property_type, svg_native_type, header_in cludes, cpp_includes
353
354 ################################################################################
355 # Not type functions?
356 ################################################################################
357
358
359 def is_read_only(attribute):
360 return attribute.is_read_only and 'Replaceable' not in attribute.extended_at tributes
361
362
363 def is_constructable(interface):
364 return any([name in interface.extended_attributes
365 for name in ['CustomConstructor', 'Constructor', 'ConstructorTem plate']])
366
367
368 def has_custom_constructor(interface):
369 return 'CustomConstructor' in interface.extended_attributes
370
371
372 def has_custom_implementation(operation):
373 return operation and 'Custom' in operation.extended_attributes
374
375
376 def has_custom_getter(attribute):
377 return any([name in attribute.extended_attributes
378 for name in ['Custom', 'CustomGetter']])
379
380
381 def has_custom_setter(attribute):
382 return any([name in attribute.extended_attributes
383 for name in ['Custom', 'CustomSetter']])
384
385
386 def is_constructor_template(interface, template_name):
387 return interface.extended_attributes.get('ConstructorTemplate') == template_ name
388
389
390 def needs_opaque_root_for_gc(interface):
391 return any([name in interface.extended_attributes
392 for name in ['GenerateIsReachable', 'CustomIsReachable']])
393
394
395 def get_context_enable_function(interface_or_attribute_or_function):
396 # If a parameter is given (e.g. 'EnabledPerContext=FeatureName') return the {FeatureName}Allowed() method.
397 enabled_per_context = interface_or_attribute_or_function.extended_attributes .get('EnabledPerContext')
398 if enabled_per_context and interface_or_attribute_or_function.extended_attri butes.get('EnabledPerContext') is not None:
399 return 'ContextFeatures::%sEnabled' % uncapitalize(enabled_per_context)
400
401 # Or it fallbacks to the attribute name if the parameter value is missing.
402 return 'ContextFeatures::%sEnabled' % uncapitalize(interface_or_attribute_or _function.name)
403
404
405 def set_callback_function_types(callback_functions):
406 callback_function_types = set(callback_functions)
407
408
409 def set_enum_types(enumerations):
410 enum_types = dict([[enum.name, enum.values] for enum in enumerations.values( )])
411
412
413 def get_enum_values(data_type):
414 return enum_types.get(data_type, [])
415
416
417 def get_native_type(idl_type, called_by_webcore=False, used_as_parameter=False, used_to_assign_js_value=False, extended_attributes=None):
418 """
419 Return native type corresponds to IDL type.
420 @param[in] idl_type ... IDL type
421 @param[in] called_by_webcore
422 @param[in] used_as_parameter
423
424 TODO support used_as_parameter for all types
425 """
426 extended_attributes = extended_attributes or {}
427 # print '[get_native_type]', type
428 if idl_type in ['float', 'double', 'long long', 'unsigned long long']:
429 return idl_type
430 if idl_type in ['int', 'long', 'short', 'byte']:
431 return 'int'
432 if idl_type in ['unsigned long', 'unsigned int', 'unsigned short', 'octet']:
433 return 'unsigned'
434 if idl_type == 'boolean':
435 return 'bool'
436 if idl_type == 'DOMString' or is_enum_type(idl_type):
437 if used_to_assign_js_value:
438 # FIXME: This implements [TreatNullAs=NullString] and [TreatUndefine dAs=NullString],
439 # but the Web IDL spec requires [TreatNullAs=EmptyString] and [Treat UndefinedAs=EmptyString].
440 mode = ''
441 if extended_attributes.get('TreatNullAs') == 'NullString' and extend ed_attributes.get('TreatUndefinedAs') == 'NullString':
442 mode = 'WithUndefinedOrNullCheck'
443 elif extended_attributes.get('TreatNullAs') == 'NullString' or 'Refl ect' in extended_attributes:
444 mode = 'WithNullCheck'
445 # FIXME: Add the case for 'elsif ($attributeOrParameter->extendedAtt ributes->{'TreatUndefinedAs'} and $attributeOrParameter->extendedAttributes->{'T reatUndefinedAs'} eq 'NullString'))'.
446 return 'V8StringResource<%s>' % mode
447 if called_by_webcore:
448 return 'const String&'
449 return 'String'
450
451 # FIXME: remove this!!! :(
452 adhoc_rules = {
453 'CompareHow': 'Range::CompareHow',
454 'DOMTimeStamp': 'DOMTimeStamp',
455 'Date': 'double',
456 'Dictionary': 'Dictionary',
457 'DOMStringList': 'RefPtr<DOMStringList>',
458 'MediaQueryListListener': 'RefPtr<MediaQueryListListener>',
459 'NodeFilter': 'RefPtr<NodeFilter>',
460 'SerializedScriptValue': 'RefPtr<SerializedScriptValue>',
461 'XPathNSResolver': 'RefPtr<XPathNSResolver>',
462 }
463 if idl_type in adhoc_rules:
464 if used_as_parameter:
465 return adhoc_rules[idl_type].replace('RefPtr', 'PassRefPtr')
466 return adhoc_rules[idl_type]
467 if idl_type == 'any' or is_callback_function_type(idl_type):
468 return 'ScriptValue'
469
470 if is_union_type(idl_type):
471 raise Exception('UnionType is not supported')
472
473 if idl_type == 'ArrayBuffer':
474 if used_as_parameter:
475 return 'ArrayBuffer*'
476 else:
477 return 'RefPtr<ArrayBuffer>'
478
479 # We need to check [ImplementedAs] extended attribute for wrapper types.
480 if is_wrapper_type(idl_type):
481 # print '[] parse_interface', idl_type
482 idl_type = implemented_as_cpp_name_from_idl_type(idl_type)
483
484 array_or_sequence_type = get_array_or_sequence_type(idl_type)
485 if array_or_sequence_type:
486 idl_type = get_native_type(array_or_sequence_type)
487 idl_type = idl_type.replace('>', '> ')
488 return 'Vector<%s>' % idl_type
489
490 if called_by_webcore:
491 return idl_type + '*'
492 elif used_to_assign_js_value:
493 return idl_type + '*'
494 elif used_as_parameter:
495 if idl_type.endswith('>'):
496 idl_type += ' '
497 return 'PassRefPtr<%s>' % idl_type
498 else:
499 return 'RefPtr<%s>' % idl_type
500
501
502 def get_is_null_expression(data_type, variable_name):
503 if is_union_type(data_type):
504 expression = []
505 for i, union_member_type in enumerate(data_type.union_member_types):
506 union_member_variable = '%s%d' % (variable_name, i)
507 is_null_expression = get_is_null_expression(union_member_type, union _member_variable)
508 expression.append(is_null_expression)
509 return ' && '.join(expression)
510 if is_ref_ptr_type(data_type):
511 return '!' + variable_name
512 elif data_type == 'DOMString':
513 return variable_name + '.isNull()'
514 return ''
515
516
517 def get_is_standard_function(interface, function):
518 return not(
519 any([key in function.extended_attributes for key in ['Unforgeable', 'Ena bledAtRuntime', 'EnabledPerContext', 'DoNotCheckSignature', 'NotEnumerable', 'Re adOnly']]) or
520 function.is_static or
521 get_requires_custom_signature(function) or
522 ('DoNotCheckSecurity' in function.extended_attributes and 'CheckSecurity ' in interface.extended_attributes or interface.name == 'Window'))
523
524
525 def get_requires_custom_signature(operation):
526 return (not(
527 # No signature needed for Custom function
528 has_custom_implementation(operation) or
529 # No signature needed for overloaded function
530 len(operation.overloads) > 1 or
531 operation.is_static or
532 operation.extended_attributes.get('StrictTypeChecking') or
533 any([parameter.is_optional and not parameter.extended_attributes.get ('Default') or is_callback_interface_etc(parameter.data_type) for parameter in o peration.arguments])) and
534 any([is_wrapper_type(parameter.data_type) for parameter in operation.arg uments]))
OLDNEW
« no previous file with comments | « Source/bindings/scripts/v8_special_accessors.py ('k') | Source/bindings/scripts/v8_utilities.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698