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

Side by Side Diff: bindings/dart/scripts/dart_interface.py

Issue 1660113002: Updated to Chrome 45 (2454) moved from SVN to git. Base URL: https://github.com/dart-lang/webcore.git@roll_45
Patch Set: Created 4 years, 10 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 | « bindings/dart/scripts/dart_dictionary.py ('k') | bindings/dart/scripts/dart_methods.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 # coding=utf-8
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
6 # met:
7 #
8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above
11 # copyright notice, this list of conditions and the following disclaimer
12 # in the documentation and/or other materials provided with the
13 # distribution.
14 # * Neither the name of Google Inc. nor the names of its
15 # contributors may be used to endorse or promote products derived from
16 # this software without specific prior written permission.
17 #
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 """Generate template values for an interface.
31
32 Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
33 """
34
35 from collections import defaultdict
36 import itertools
37 from operator import itemgetter
38
39 import idl_types
40 from idl_types import IdlType, inherits_interface, IdlArrayOrSequenceType, IdlAr rayType
41 import dart_attributes
42 import dart_methods
43 import dart_types
44 from dart_utilities import DartUtilities
45 from v8_globals import includes
46 import v8_attributes
47 import v8_interface
48
49
50 INTERFACE_H_INCLUDES = frozenset([
51 'bindings/core/dart/DartDOMWrapper.h',
52 'platform/heap/Handle.h',
53 ])
54
55 INTERFACE_CPP_INCLUDES = frozenset([
56
57 'bindings/core/dart/DartUtilities.h',
58 'wtf/GetPtr.h',
59 'wtf/RefPtr.h',
60 ])
61
62
63 # TODO(terry): Temporary to not generate a method, getter/setter. Format is:
64 #
65 # interface_name.method_name
66 # interface_name.get:attribute_name
67 # interface_name.set:attribute_name
68 #
69 # Ultimate solution add a special attribute flag to IDL to signal
70 # don't generate IDL entry in Dart (e.g., DartNoGenerate)?
71 IGNORE_MEMBERS = frozenset([
72 'AudioBufferSourceNode.looping', # TODO(vsm): Use deprecated IDL annotation
73 'CSSStyleDeclaration.getPropertyCSSValue',
74 'CanvasRenderingContext2D.clearShadow',
75 'CanvasRenderingContext2D.drawImageFromRect',
76 'CanvasRenderingContext2D.setAlpha',
77 'CanvasRenderingContext2D.setCompositeOperation',
78 'CanvasRenderingContext2D.setFillColor',
79 'CanvasRenderingContext2D.setLineCap',
80 'CanvasRenderingContext2D.setLineJoin',
81 'CanvasRenderingContext2D.setLineWidth',
82 'CanvasRenderingContext2D.setMiterLimit',
83 'CanvasRenderingContext2D.setShadow',
84 'CanvasRenderingContext2D.setStrokeColor',
85 'CharacterData.remove',
86 'Window.call:blur',
87 'Window.call:focus',
88 'Window.clientInformation',
89 'Window.createImageBitmap',
90 'Window.get:frames',
91 'Window.get:length',
92 'Window.on:beforeUnload',
93 'Window.on:webkitTransitionEnd',
94 'Window.pagePopupController',
95 'Window.prompt',
96 'Window.webkitCancelAnimationFrame',
97 'Window.webkitCancelRequestAnimationFrame',
98 'Window.webkitIndexedDB',
99 'Window.webkitRequestAnimationFrame',
100 'Document.alinkColor',
101 'HTMLDocument.all',
102 'Document.applets',
103 'Document.bgColor',
104 'Document.clear',
105 'Document.createAttribute',
106 'Document.createAttributeNS',
107 'Document.createComment',
108 'Document.createExpression',
109 'Document.createNSResolver',
110 'Document.createProcessingInstruction',
111 'Document.designMode',
112 'Document.dir',
113 'Document.evaluate',
114 'Document.fgColor',
115 'Document.get:URL',
116 'Document.get:anchors',
117 'Document.get:characterSet',
118 'Document.get:compatMode',
119 'Document.get:defaultCharset',
120 'Document.get:doctype',
121 'Document.get:documentURI',
122 'Document.get:embeds',
123 'Document.get:forms',
124 'Document.get:inputEncoding',
125 'Document.get:links',
126 'Document.get:plugins',
127 'Document.get:scripts',
128 'Document.get:xmlEncoding',
129 'Document.getElementsByTagNameNS',
130 'Document.getOverrideStyle',
131 'Document.getSelection',
132 'Document.images',
133 'Document.linkColor',
134 'Document.location',
135 'Document.on:wheel',
136 'Document.open',
137 'Document.register',
138 'Document.set:domain',
139 'Document.vlinkColor',
140 'Document.webkitCurrentFullScreenElement',
141 'Document.webkitFullScreenKeyboardInputAllowed',
142 'Document.write',
143 'Document.writeln',
144 'Document.xmlStandalone',
145 'Document.xmlVersion',
146 'DocumentFragment.children',
147 'DocumentType.*',
148 'DOMException.code',
149 'DOMException.ABORT_ERR',
150 'DOMException.DATA_CLONE_ERR',
151 'DOMException.DOMSTRING_SIZE_ERR',
152 'DOMException.HIERARCHY_REQUEST_ERR',
153 'DOMException.INDEX_SIZE_ERR',
154 'DOMException.INUSE_ATTRIBUTE_ERR',
155 'DOMException.INVALID_ACCESS_ERR',
156 'DOMException.INVALID_CHARACTER_ERR',
157 'DOMException.INVALID_MODIFICATION_ERR',
158 'DOMException.INVALID_NODE_TYPE_ERR',
159 'DOMException.INVALID_STATE_ERR',
160 'DOMException.NAMESPACE_ERR',
161 'DOMException.NETWORK_ERR',
162 'DOMException.NOT_FOUND_ERR',
163 'DOMException.NOT_SUPPORTED_ERR',
164 'DOMException.NO_DATA_ALLOWED_ERR',
165 'DOMException.NO_MODIFICATION_ALLOWED_ERR',
166 'DOMException.QUOTA_EXCEEDED_ERR',
167 'DOMException.SECURITY_ERR',
168 'DOMException.SYNTAX_ERR',
169 'DOMException.TIMEOUT_ERR',
170 'DOMException.TYPE_MISMATCH_ERR',
171 'DOMException.URL_MISMATCH_ERR',
172 'DOMException.VALIDATION_ERR',
173 'DOMException.WRONG_DOCUMENT_ERR',
174 'Element.accessKey',
175 'Element.dataset',
176 'Element.get:classList',
177 'Element.getAttributeNode',
178 'Element.getAttributeNodeNS',
179 'Element.getElementsByTagNameNS',
180 'Element.innerText',
181 'Element.on:wheel',
182 'Element.outerText',
183 'Element.removeAttributeNode',
184 'Element.set:outerHTML',
185 'Element.setAttributeNode',
186 'Element.setAttributeNodeNS',
187 'Element.webkitCreateShadowRoot',
188 'Element.webkitMatchesSelector',
189 'Element.webkitPseudo',
190 'Element.webkitShadowRoot',
191 '=Event.returnValue', # Only suppress on Event, allow for BeforeUnloadEvent .
192 'Event.srcElement',
193 'EventSource.URL',
194 'FontFace.ready',
195 'FontFaceSet.load',
196 'FontFaceSet.ready',
197 'HTMLAnchorElement.charset',
198 'HTMLAnchorElement.coords',
199 'HTMLAnchorElement.rev',
200 'HTMLAnchorElement.shape',
201 'HTMLAnchorElement.text',
202 'HTMLAppletElement.*',
203 'HTMLAreaElement.noHref',
204 'HTMLBRElement.clear',
205 'HTMLBaseFontElement.*',
206 'HTMLBodyElement.aLink',
207 'HTMLBodyElement.background',
208 'HTMLBodyElement.bgColor',
209 'HTMLBodyElement.link',
210 'HTMLBodyElement.on:beforeUnload',
211 'HTMLBodyElement.text',
212 'HTMLBodyElement.vLink',
213 'HTMLDListElement.compact',
214 'HTMLDirectoryElement.*',
215 'HTMLDivElement.align',
216 'HTMLFontElement.*',
217 'HTMLFormControlsCollection.__getter__',
218 'HTMLFormElement.get:elements',
219 'HTMLFrameElement.*',
220 'HTMLFrameSetElement.*',
221 'HTMLHRElement.align',
222 'HTMLHRElement.noShade',
223 'HTMLHRElement.size',
224 'HTMLHRElement.width',
225 'HTMLHeadElement.profile',
226 'HTMLHeadingElement.align',
227 'HTMLHtmlElement.manifest',
228 'HTMLHtmlElement.version',
229 'HTMLIFrameElement.align',
230 'HTMLIFrameElement.frameBorder',
231 'HTMLIFrameElement.longDesc',
232 'HTMLIFrameElement.marginHeight',
233 'HTMLIFrameElement.marginWidth',
234 'HTMLIFrameElement.scrolling',
235 'HTMLImageElement.align',
236 'HTMLImageElement.hspace',
237 'HTMLImageElement.longDesc',
238 'HTMLImageElement.name',
239 'HTMLImageElement.vspace',
240 'HTMLInputElement.align',
241 'HTMLLegendElement.align',
242 'HTMLLinkElement.charset',
243 'HTMLLinkElement.rev',
244 'HTMLLinkElement.target',
245 'HTMLMarqueeElement.*',
246 'HTMLMenuElement.compact',
247 'HTMLMetaElement.scheme',
248 'HTMLOListElement.compact',
249 'HTMLObjectElement.align',
250 'HTMLObjectElement.archive',
251 'HTMLObjectElement.border',
252 'HTMLObjectElement.codeBase',
253 'HTMLObjectElement.codeType',
254 'HTMLObjectElement.declare',
255 'HTMLObjectElement.hspace',
256 'HTMLObjectElement.standby',
257 'HTMLObjectElement.vspace',
258 'HTMLOptionElement.text',
259 'HTMLOptionsCollection.*',
260 'HTMLParagraphElement.align',
261 'HTMLParamElement.type',
262 'HTMLParamElement.valueType',
263 'HTMLPreElement.width',
264 'HTMLScriptElement.text',
265 'HTMLSelectElement.options',
266 'HTMLSelectElement.selectedOptions',
267 'HTMLTableCaptionElement.align',
268 'HTMLTableCellElement.abbr',
269 'HTMLTableCellElement.align',
270 'HTMLTableCellElement.axis',
271 'HTMLTableCellElement.bgColor',
272 'HTMLTableCellElement.ch',
273 'HTMLTableCellElement.chOff',
274 'HTMLTableCellElement.height',
275 'HTMLTableCellElement.noWrap',
276 'HTMLTableCellElement.scope',
277 'HTMLTableCellElement.vAlign',
278 'HTMLTableCellElement.width',
279 'HTMLTableColElement.align',
280 'HTMLTableColElement.ch',
281 'HTMLTableColElement.chOff',
282 'HTMLTableColElement.vAlign',
283 'HTMLTableColElement.width',
284 'HTMLTableElement.align',
285 'HTMLTableElement.bgColor',
286 'HTMLTableElement.cellPadding',
287 'HTMLTableElement.cellSpacing',
288 'HTMLTableElement.frame',
289 'HTMLTableElement.rules',
290 'HTMLTableElement.summary',
291 'HTMLTableElement.width',
292 'HTMLTableRowElement.align',
293 'HTMLTableRowElement.bgColor',
294 'HTMLTableRowElement.ch',
295 'HTMLTableRowElement.chOff',
296 'HTMLTableRowElement.vAlign',
297 'HTMLTableSectionElement.align',
298 'HTMLTableSectionElement.ch',
299 'HTMLTableSectionElement.chOff',
300 'HTMLTableSectionElement.vAlign',
301 'HTMLTitleElement.text',
302 'HTMLUListElement.compact',
303 'HTMLUListElement.type',
304 'Location.valueOf',
305 'MessageEvent.ports',
306 'MessageEvent.webkitInitMessageEvent',
307 'MouseEvent.x',
308 'MouseEvent.y',
309 'Navigator.registerServiceWorker',
310 'Navigator.unregisterServiceWorker',
311 'Node.compareDocumentPosition',
312 'Node.get:DOCUMENT_POSITION_CONTAINED_BY',
313 'Node.get:DOCUMENT_POSITION_CONTAINS',
314 'Node.get:DOCUMENT_POSITION_DISCONNECTED',
315 'Node.get:DOCUMENT_POSITION_FOLLOWING',
316 'Node.get:DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC',
317 'Node.get:DOCUMENT_POSITION_PRECEDING',
318 'Node.get:prefix',
319 'Node.hasAttributes',
320 'Node.isDefaultNamespace',
321 'Node.isEqualNode',
322 'Node.isSameNode',
323 'Node.isSupported',
324 'Node.lookupNamespaceURI',
325 'Node.lookupPrefix',
326 'Node.normalize',
327 'Node.set:nodeValue',
328 'NodeFilter.acceptNode',
329 'NodeIterator.expandEntityReferences',
330 'NodeIterator.filter',
331 'Performance.webkitClearMarks',
332 'Performance.webkitClearMeasures',
333 'Performance.webkitGetEntries',
334 'Performance.webkitGetEntriesByName',
335 'Performance.webkitGetEntriesByType',
336 'Performance.webkitMark',
337 'Performance.webkitMeasure',
338 'ShadowRoot.getElementsByTagNameNS',
339 'SVGElement.getPresentationAttribute',
340 'SVGElementInstance.on:wheel',
341 'WheelEvent.wheelDelta',
342 'Window.on:wheel',
343 'WindowEventHandlers.on:beforeUnload',
344 'WorkerGlobalScope.webkitIndexedDB',
345 # TODO(jacobr): should these be removed?
346 'Document.close',
347 'Document.hasFocus',
348 ])
349
350
351 def _suppress_method(interface_name, name):
352 name_to_find = '%s.%s' % (interface_name, name)
353 wildcard_name_to_find = '%s.*' % interface_name
354 return name_to_find in IGNORE_MEMBERS or wildcard_name_to_find in IGNORE_MEM BERS
355
356
357 # Both getter and setter are to be suppressed then the attribute is completely
358 # disappear.
359 def _suppress_attribute(interface_name, name):
360 return (suppress_getter(interface_name, name) and suppress_setter(interface_ name, name))
361
362
363 def suppress_getter(interface_name, name):
364 name_to_find = '%s.get:%s' % (interface_name, name)
365 wildcard_getter_to_find = '%s.get:*' % interface_name
366 return (name_to_find in IGNORE_MEMBERS or
367 _suppress_method(interface_name, name) or
368 wildcard_getter_to_find in IGNORE_MEMBERS)
369
370
371 def suppress_setter(interface_name, name):
372 name_to_find = '%s.set:%s' % (interface_name, name)
373 wildcard_setter_to_find = '%s.set:*' % interface_name
374 return (name_to_find in IGNORE_MEMBERS or
375 _suppress_method(interface_name, name) or
376 wildcard_setter_to_find in IGNORE_MEMBERS)
377
378
379 # To suppress an IDL method or attribute with a particular Extended Attribute
380 # w/o a value e.g, DartStrictTypeChecking would be an empty set
381 # 'DartStrictTypeChecking': frozenset([]),
382 IGNORE_EXTENDED_ATTRIBUTES = {
383 # 'RuntimeEnabled': frozenset(['ExperimentalCanvasFeatures']),
384 }
385
386
387 # Return True if the method / attribute should be suppressed.
388 def _suppress_extended_attributes(extended_attributes):
389 if 'DartSuppress' in extended_attributes and extended_attributes.get('DartSu ppress') == None:
390 return True
391
392 # TODO(terry): Eliminate this using DartSuppress extended attribute in the
393 # IDL files instead of the IGNORE_EXTENDED_ATTRIBUTES list.
394 for extended_attribute_name in extended_attributes:
395 ignore_extended_values = IGNORE_EXTENDED_ATTRIBUTES.get(extended_attribu te_name)
396 if ignore_extended_values != None:
397 extended_attribute_value = extended_attributes.get(extended_attribut e_name)
398 if ((not ignore_extended_values and extended_attribute_value == None ) or
399 extended_attribute_value in ignore_extended_values):
400 return True
401 return False
402
403
404 # TODO(terry): Rename genenerate_interface to interface_context.
405 def interface_context(interface):
406 context = v8_interface.interface_context(interface)
407
408 includes.clear()
409
410 includes.update(INTERFACE_CPP_INCLUDES)
411 header_includes = set(INTERFACE_H_INCLUDES)
412
413 parent_interface = interface.parent
414 if parent_interface:
415 header_includes.update(dart_types.includes_for_interface(parent_interfac e))
416 extended_attributes = interface.extended_attributes
417
418 is_document = inherits_interface(interface.name, 'Document')
419 if is_document:
420 # FIXME(vsm): We probably need bindings/dart/DartController and
421 # core/frame/LocalFrame.h here.
422 includes.update(['DartDocument.h'])
423
424 if inherits_interface(interface.name, 'DataTransferItemList'):
425 # FIXME(jacobr): this is a hack.
426 includes.update(['core/html/HTMLCollection.h'])
427
428
429 if inherits_interface(interface.name, 'EventTarget'):
430 includes.update(['bindings/core/dart/DartEventListener.h'])
431
432 # [SetWrapperReferenceTo]
433 set_wrapper_reference_to_list = [{
434 'name': argument.name,
435 # FIXME: properly should be:
436 # 'cpp_type': argument.idl_type.cpp_type_args(used_as_rvalue_type=True),
437 # (if type is non-wrapper type like NodeFilter, normally RefPtr)
438 # Raw pointers faster though, and NodeFilter hacky anyway.
439 'cpp_type': argument.idl_type.implemented_as + '*',
440 'idl_type': argument.idl_type,
441 'v8_type': dart_types.v8_type(argument.idl_type.name),
442 } for argument in extended_attributes.get('SetWrapperReferenceTo', [])]
443 for set_wrapper_reference_to in set_wrapper_reference_to_list:
444 set_wrapper_reference_to['idl_type'].add_includes_for_type()
445
446 context.update({
447 'conditional_string': DartUtilities.conditional_string(interface), # [C onditional]
448 'cpp_class': DartUtilities.cpp_name(interface),
449 'header_includes': header_includes,
450 'is_garbage_collected': context['gc_type'] == 'GarbageCollectedObject',
451 'is_will_be_garbage_collected': context['gc_type'] == 'WillBeGarbageColl ectedObject',
452 'measure_as': DartUtilities.measure_as(interface), # [MeasureAs]
453 'pass_cpp_type': dart_types.cpp_template_type(
454 dart_types.cpp_ptr_type('PassRefPtr', 'RawPtr', context['gc_type']),
455 DartUtilities.cpp_name(interface)),
456 'runtime_enabled_function': DartUtilities.runtime_enabled_function_name( interface), # [RuntimeEnabled]
457 'set_wrapper_reference_to_list': set_wrapper_reference_to_list,
458 'dart_class': dart_types.dart_type(interface.name),
459 'v8_class': DartUtilities.v8_class_name(interface),
460 })
461
462 # Constructors
463 constructors = [constructor_context(interface, constructor)
464 for constructor in interface.constructors
465 # FIXME: shouldn't put named constructors with constructors
466 # (currently needed for Perl compatibility)
467 # Handle named constructors separately
468 if constructor.name == 'Constructor']
469 if len(constructors) > 1:
470 context.update({'constructor_overloads': overloads_context(constructors) })
471
472 # [CustomConstructor]
473 custom_constructors = [custom_constructor_context(interface, constructor)
474 for constructor in interface.custom_constructors]
475
476 # [NamedConstructor]
477 named_constructor = generate_named_constructor(interface)
478
479 generate_method_native_entries(interface, constructors, 'Constructor')
480 generate_method_native_entries(interface, custom_constructors, 'Constructor' )
481 if named_constructor:
482 generate_method_native_entries(interface, [named_constructor],
483 'Constructor')
484 event_constructor = None
485 if context['has_event_constructor']:
486 event_constructor = {
487 'native_entries': [
488 DartUtilities.generate_native_entry(
489 interface.name, None, 'Constructor', False, 2)],
490 }
491
492 if (context['constructors'] or custom_constructors or context['has_event_con structor'] or
493 named_constructor):
494 includes.add('core/frame/LocalDOMWindow.h')
495
496 context.update({
497 'constructors': constructors,
498 'custom_constructors': custom_constructors,
499 'event_constructor': event_constructor,
500 'has_custom_constructor': bool(custom_constructors),
501 'interface_length':
502 v8_interface.interface_length(interface, constructors + custom_const ructors),
503 'is_constructor_call_with_document': DartUtilities.has_extended_attribut e_value(
504 interface, 'ConstructorCallWith', 'Document'), # [ConstructorCallWi th=Document]
505 'is_constructor_call_with_execution_context': DartUtilities.has_extended _attribute_value(
506 interface, 'ConstructorCallWith', 'ExecutionContext'), # [Construct orCallWith=ExeuctionContext]
507 'named_constructor': named_constructor,
508 })
509
510 # Attributes
511 attributes = [dart_attributes.attribute_context(interface, attribute)
512 for attribute in interface.attributes
513 # Skip attributes in the IGNORE_MEMBERS list or if an
514 # extended attribute is in the IGNORE_EXTENDED_ATTRIBUTES.
515 if (not _suppress_attribute(interface.name, attribute.name ) and
516 not v8_attributes.is_constructor_attribute(attribute) and
517 not _suppress_extended_attributes(attribute.extended_a ttributes) and
518 not ('DartSuppress' in attribute.extended_attributes a nd
519 attribute.extended_attributes.get('DartSuppress') == None))]
520 context.update({
521 'attributes': attributes,
522 'has_accessors': any(attribute['is_expose_js_accessors'] for attribute i n attributes),
523 'has_attribute_configuration': any(
524 not (attribute['is_expose_js_accessors'] or
525 attribute['is_static'] or
526 attribute['runtime_enabled_function'] or
527 attribute['per_context_enabled_function'])
528 for attribute in attributes),
529 'has_constructor_attributes': any(attribute['constructor_type'] for attr ibute in attributes),
530 'has_per_context_enabled_attributes': any(attribute['per_context_enabled _function'] for attribute in attributes),
531 'has_replaceable_attributes': any(attribute['is_replaceable'] for attrib ute in attributes),
532 })
533
534 # Methods
535 methods = [dart_methods.method_context(interface, method)
536 for method in interface.operations
537 # Skip anonymous special operations (methods name empty).
538 # Skip methods in our IGNORE_MEMBERS list.
539 # Skip methods w/ extended attributes in IGNORE_EXTENDED_ATTRIBUT ES list.
540 if (method.name and
541 # detect unnamed getters from v8_interface.
542 method.name != 'anonymousNamedGetter' and
543 # TODO(terry): Eventual eliminate the IGNORE_MEMBERS in favor of DartSupress.
544 not _suppress_method(interface.name, method.name) and
545 not _suppress_extended_attributes(method.extended_attributes) and
546 not 'DartSuppress' in method.extended_attributes)]
547 compute_method_overloads_context(methods)
548 for method in methods:
549 method['do_generate_method_configuration'] = (
550 method['do_not_check_signature'] and
551 not method['per_context_enabled_function'] and
552 # For overloaded methods, only generate one accessor
553 ('overload_index' not in method or method['overload_index'] == 1))
554
555 generate_method_native_entries(interface, methods, 'Method')
556
557 context.update({
558 'has_origin_safe_method_setter': any(
559 method['is_check_security_for_frame'] and not method['is_read_only']
560 for method in methods),
561 'has_method_configuration': any(method['do_generate_method_configuration '] for method in methods),
562 'has_per_context_enabled_methods': any(method['per_context_enabled_funct ion'] for method in methods),
563 'methods': methods,
564 })
565
566 context.update({
567 'indexed_property_getter': indexed_property_getter(interface),
568 'indexed_property_setter': indexed_property_setter(interface),
569 'indexed_property_deleter': v8_interface.indexed_property_deleter(interf ace),
570 'is_override_builtins': 'OverrideBuiltins' in extended_attributes,
571 'named_property_getter': named_property_getter(interface),
572 'named_property_setter': named_property_setter(interface),
573 'named_property_deleter': v8_interface.named_property_deleter(interface) ,
574 })
575
576 generate_native_entries_for_specials(interface, context)
577
578 native_entries = generate_interface_native_entries(context)
579
580 context.update({
581 'native_entries': native_entries,
582 })
583
584 return context
585
586
587 def generate_interface_native_entries(context):
588 entries = {}
589
590 def add(ne):
591 entries[ne['blink_entry']] = ne
592
593 def addAll(nes):
594 for ne in nes:
595 add(ne)
596
597 for constructor in context['constructors']:
598 addAll(constructor['native_entries'])
599 for constructor in context['custom_constructors']:
600 addAll(constructor['native_entries'])
601 if context['named_constructor']:
602 addAll(context['named_constructor']['native_entries'])
603 if context['event_constructor']:
604 addAll(context['event_constructor']['native_entries'])
605 for method in context['methods']:
606 addAll(method['native_entries'])
607 for attribute in context['attributes']:
608 add(attribute['native_entry_getter'])
609 if not attribute['is_read_only'] or attribute['put_forwards']:
610 add(attribute['native_entry_setter'])
611 if context['indexed_property_getter']:
612 addAll(context['indexed_property_getter']['native_entries'])
613 if context['indexed_property_setter']:
614 addAll(context['indexed_property_setter']['native_entries'])
615 if context['indexed_property_deleter']:
616 addAll(context['indexed_property_deleter']['native_entries'])
617 if context['named_property_getter']:
618 addAll(context['named_property_getter']['native_entries'])
619 if context['named_property_setter']:
620 addAll(context['named_property_setter']['native_entries'])
621 if context['named_property_deleter']:
622 addAll(context['named_property_deleter']['native_entries'])
623 return list(entries.values())
624
625
626 def generate_method_native_entry(interface, method, count, kind):
627 name = method.get('name')
628 is_static = bool(method.get('is_static'))
629 native_entry = \
630 DartUtilities.generate_native_entry(interface.name, name,
631 kind, is_static, count)
632 return native_entry
633
634
635 def generate_method_native_entries(interface, methods, kind):
636 for method in methods:
637 native_entries = []
638 arg_count = method['number_of_arguments']
639 min_arg_count = method['number_of_required_arguments']
640 lb = min_arg_count - 2 if min_arg_count > 2 else 0
641 for x in range(lb, arg_count + 3):
642 native_entry = \
643 generate_method_native_entry(interface, method, x, kind)
644 native_entries.append(native_entry)
645
646 method.update({'native_entries': native_entries})
647
648
649 ################################################################################
650 # Overloads
651 ################################################################################
652
653 def compute_method_overloads_context(methods):
654 # Regular methods
655 compute_method_overloads_context_by_type([method for method in methods
656 if not method['is_static']])
657 # Static methods
658 compute_method_overloads_context_by_type([method for method in methods
659 if method['is_static']])
660
661
662 def compute_method_overloads_context_by_type(methods):
663 """Computes |method.overload*| template values.
664
665 Called separately for static and non-static (regular) methods,
666 as these are overloaded separately.
667 Modifies |method| in place for |method| in |methods|.
668 Doesn't change the |methods| list itself (only the values, i.e. individual
669 methods), so ok to treat these separately.
670 """
671 # Add overload information only to overloaded methods, so template code can
672 # easily verify if a function is overloaded
673 for name, overloads in v8_interface.method_overloads_by_name(methods):
674 # Resolution function is generated after last overloaded function;
675 # package necessary information into |method.overloads| for that method.
676 overloads[-1]['overloads'] = overloads_context(overloads)
677 overloads[-1]['overloads']['name'] = name
678
679
680 def overloads_context(overloads):
681 """Returns |overloads| template values for a single name.
682
683 Sets |method.overload_index| in place for |method| in |overloads|
684 and returns dict of overall overload template values.
685 """
686 assert len(overloads) > 1 # only apply to overloaded names
687 for index, method in enumerate(overloads, 1):
688 method['overload_index'] = index
689
690 effective_overloads_by_length = v8_interface.effective_overload_set_by_lengt h(overloads)
691 lengths = [length for length, _ in effective_overloads_by_length]
692 name = overloads[0].get('name', '<constructor>')
693
694 # Check and fail if all overloads with the shortest acceptable arguments
695 # list are runtime enabled, since we would otherwise set 'length' on the
696 # function object to an incorrect value when none of those overloads were
697 # actually enabled at runtime. The exception is if all overloads are
698 # controlled by the same runtime enabled feature, in which case there would
699 # be no function object at all if it is not enabled.
700 shortest_overloads = effective_overloads_by_length[0][1]
701 if (all(method.get('runtime_enabled_function')
702 for method, _, _ in shortest_overloads) and
703 not v8_interface.common_value(overloads, 'runtime_enabled_function')):
704 raise ValueError('Function.length of %s depends on runtime enabled featu res' % name)
705
706 return {
707 'deprecate_all_as': v8_interface.common_value(overloads, 'deprecate_as') , # [DeprecateAs]
708 'exposed_test_all': v8_interface.common_value(overloads, 'exposed_test') , # [Exposed]
709 'length_tests_methods': length_tests_methods(effective_overloads_by_leng th),
710 # 1. Let maxarg be the length of the longest type list of the
711 # entries in S.
712 'maxarg': lengths[-1],
713 'measure_all_as': v8_interface.common_value(overloads, 'measure_as'), # [MeasureAs]
714 'minarg': lengths[0],
715 'per_context_enabled_function_all': v8_interface.common_value(overloads, 'per_context_enabled_function'), # [PerContextEnabled]
716 'runtime_enabled_function_all': v8_interface.common_value(overloads, 'ru ntime_enabled_function'), # [RuntimeEnabled]
717 'valid_arities': lengths
718 # Only need to report valid arities if there is a gap in the
719 # sequence of possible lengths, otherwise invalid length means
720 # "not enough arguments".
721 if lengths[-1] - lengths[0] != len(lengths) - 1 else None,
722 }
723
724
725 def length_tests_methods(effective_overloads_by_length):
726 """Returns sorted list of resolution tests and associated methods, by length .
727
728 This builds the main data structure for the overload resolution loop.
729 For a given argument length, bindings test argument at distinguishing
730 argument index, in order given by spec: if it is compatible with
731 (optionality or) type required by an overloaded method, resolve to that
732 method.
733
734 Returns:
735 [(length, [(test, method)])]
736 """
737 return [(length, list(resolution_tests_methods(effective_overloads)))
738 for length, effective_overloads in effective_overloads_by_length]
739
740
741 DART_CHECK_TYPE = {
742 'ArrayBufferView': 'Dart_IsTypedData({cpp_value})',
743 'ArrayBuffer': 'Dart_IsByteBuffer({cpp_value})',
744 'Uint8Array': 'DartUtilities::isUint8Array({cpp_value})',
745 'Uint8ClampedArray': 'DartUtilities::isUint8ClampedArray({cpp_value})',
746 }
747
748
749 def resolution_tests_methods(effective_overloads):
750 """Yields resolution test and associated method, in resolution order, for ef fective overloads of a given length.
751
752 This is the heart of the resolution algorithm.
753 http://heycam.github.io/webidl/#dfn-overload-resolution-algorithm
754
755 Note that a given method can be listed multiple times, with different tests!
756 This is to handle implicit type conversion.
757
758 Returns:
759 [(test, method)]
760 """
761 methods = [effective_overload[0]
762 for effective_overload in effective_overloads]
763 if len(methods) == 1:
764 # If only one method with a given length, no test needed
765 yield 'true', methods[0]
766 return
767
768 # 6. If there is more than one entry in S, then set d to be the
769 # distinguishing argument index for the entries of S.
770 index = v8_interface.distinguishing_argument_index(effective_overloads)
771 # (7-9 are for handling |undefined| values for optional arguments before
772 # the distinguishing argument (as "missing"), so you can specify only some
773 # optional arguments. We don't support this, so we skip these steps.)
774 # 10. If i = d, then:
775 # (d is the distinguishing argument index)
776 # 1. Let V be argi.
777 # Note: This is the argument that will be used to resolve which
778 # overload is selected.
779 cpp_value = 'Dart_GetNativeArgument(args, %s + argOffset)' % index
780
781 # Extract argument and IDL type to simplify accessing these in each loop.
782 arguments = [method['arguments'][index] for method in methods]
783 arguments_methods = zip(arguments, methods)
784 idl_types = [argument['idl_type_object'] for argument in arguments]
785 idl_types_methods = zip(idl_types, methods)
786
787 # We can't do a single loop through all methods or simply sort them, because
788 # a method may be listed in multiple steps of the resolution algorithm, and
789 # which test to apply differs depending on the step.
790 #
791 # Instead, we need to go through all methods at each step, either finding
792 # first match (if only one test is allowed) or filtering to matches (if
793 # multiple tests are allowed), and generating an appropriate tests.
794
795 # 2. If V is undefined, and there is an entry in S whose list of
796 # optionality values has "optional" at index i, then remove from S all
797 # other entries.
798 try:
799 method = next(method for argument, method in arguments_methods
800 if argument['is_optional'])
801 test = 'Dart_IsNull(%s)' % cpp_value
802 yield test, method
803 except StopIteration:
804 pass
805
806 # 3. Otherwise: if V is null or undefined, and there is an entry in S that
807 # has one of the following types at position i of its type list,
808 # - a nullable type
809 try:
810 method = next(method for idl_type, method in idl_types_methods
811 if idl_type.is_nullable)
812 test = 'Dart_IsNull(%s)' % cpp_value
813 yield test, method
814 except StopIteration:
815 pass
816
817 # 4. Otherwise: if V is a platform object - but not a platform array
818 # object - and there is an entry in S that has one of the following
819 # types at position i of its type list,
820 # - an interface type that V implements
821 # (Unlike most of these tests, this can return multiple methods, since we
822 # test if it implements an interface. Thus we need a for loop, not a next.)
823 # (We distinguish wrapper types from built-in interface types.)
824 for idl_type, method in ((idl_type, method)
825 for idl_type, method in idl_types_methods
826 if idl_type.is_wrapper_type):
827 fmtstr = 'Dart{idl_type}::hasInstance({cpp_value})'
828 if idl_type.base_type in DART_CHECK_TYPE:
829 fmtstr = DART_CHECK_TYPE[idl_type.base_type]
830 test = fmtstr.format(idl_type=idl_type.base_type, cpp_value=cpp_value)
831 yield test, method
832
833 # 8. Otherwise: if V is any kind of object except for a native Date object,
834 # a native RegExp object, and there is an entry in S that has one of the
835 # following types at position i of its type list,
836 # - an array type
837 # - a sequence type
838 # ...
839 # - a dictionary
840 try:
841 # FIXME: IDL dictionary not implemented, so use Blink Dictionary
842 # http://crbug.com/321462
843 idl_type, method = next((idl_type, method)
844 for idl_type, method in idl_types_methods
845 if (idl_type.native_array_element_type or
846 idl_type.name == 'Dictionary'))
847 if idl_type.native_array_element_type:
848 # (We test for Array instead of generic Object to type-check.)
849 # FIXME: test for Object during resolution, then have type check for
850 # Array in overloaded method: http://crbug.com/262383
851 test = 'Dart_IsList(%s)' % cpp_value
852 else:
853 # FIXME: should be '{1}->IsObject() && !{1}->IsDate() && !{1}->IsReg Exp()'.format(cpp_value)
854 # FIXME: the IsDate and IsRegExp checks can be skipped if we've
855 # already generated tests for them.
856 test = 'Dart_IsInstance(%s)' % cpp_value
857 yield test, method
858 except StopIteration:
859 pass
860
861 # (Check for exact type matches before performing automatic type conversion;
862 # only needed if distinguishing between primitive types.)
863 if len([idl_type.is_primitive_type for idl_type in idl_types]) > 1:
864 # (Only needed if match in step 11, otherwise redundant.)
865 if any(idl_type.is_string_type or idl_type.is_enum
866 for idl_type in idl_types):
867 # 10. Otherwise: if V is a Number value, and there is an entry in S
868 # that has one of the following types at position i of its type
869 # list,
870 # - a numeric type
871 try:
872 method = next(method for idl_type, method in idl_types_methods
873 if idl_type.is_numeric_type)
874 test = 'Dart_IsNumber(%s)' % cpp_value
875 yield test, method
876 except StopIteration:
877 pass
878
879 # (Perform automatic type conversion, in order. If any of these match,
880 # that's the end, and no other tests are needed.) To keep this code simple,
881 # we rely on the C++ compiler's dead code elimination to deal with the
882 # redundancy if both cases below trigger.
883
884 # 11. Otherwise: if there is an entry in S that has one of the following
885 # types at position i of its type list,
886 # - DOMString
887 # - ByteString
888 # - ScalarValueString [a DOMString typedef, per definition.]
889 # - an enumeration type
890 try:
891 method = next(method for idl_type, method in idl_types_methods
892 if idl_type.is_string_type or idl_type.is_enum)
893 yield 'true', method
894 except StopIteration:
895 pass
896
897 # 12. Otherwise: if there is an entry in S that has one of the following
898 # types at position i of its type list,
899 # - a numeric type
900 try:
901 method = next(method for idl_type, method in idl_types_methods
902 if idl_type.is_numeric_type)
903 yield 'true', method
904 except StopIteration:
905 pass
906
907
908 ################################################################################
909 # Constructors
910 ################################################################################
911
912 # [Constructor]
913 def custom_constructor_context(interface, constructor):
914 return {
915 'arguments': [custom_constructor_argument(argument, index)
916 for index, argument in enumerate(constructor.arguments)],
917 'auto_scope': 'true',
918 'is_auto_scope': True,
919 'is_call_with_script_arguments': False,
920 'is_custom': True,
921 'number_of_arguments': len(constructor.arguments),
922 'number_of_required_arguments':
923 v8_interface.number_of_required_arguments(constructor),
924 }
925
926
927 # We don't need much from this - just the idl_type_objects and preproceed_type
928 # to use in generating the resolver strings.
929 def custom_constructor_argument(argument, index):
930 return {
931 'idl_type_object': argument.idl_type,
932 'name': argument.name,
933 'preprocessed_type': str(argument.idl_type.preprocessed_type),
934 }
935
936
937 # [Constructor]
938 def constructor_context(interface, constructor):
939 return {
940 'arguments': [dart_methods.argument_context(interface, constructor, argu ment, index)
941 for index, argument in enumerate(constructor.arguments)],
942 'auto_scope': 'true',
943 'cpp_value': dart_methods.cpp_value(
944 interface, constructor, len(constructor.arguments)),
945 'has_exception_state':
946 # [RaisesException=Constructor]
947 interface.extended_attributes.get('RaisesException') == 'Constructor ' or
948 any(argument for argument in constructor.arguments
949 if argument.idl_type.name == 'SerializedScriptValue' or
950 argument.idl_type.is_integer_type),
951 'is_auto_scope': True,
952 'is_call_with_script_arguments': False,
953 'is_constructor': True,
954 'is_custom': False,
955 'is_variadic': False, # Required for overload resolution
956 'number_of_required_arguments':
957 v8_interface.number_of_required_arguments(constructor),
958 'number_of_arguments': len(constructor.arguments),
959 }
960
961
962 # [NamedConstructor]
963 def generate_named_constructor(interface):
964 extended_attributes = interface.extended_attributes
965 if 'NamedConstructor' not in extended_attributes:
966 return None
967 # FIXME: parser should return named constructor separately;
968 # included in constructors (and only name stored in extended attribute)
969 # for Perl compatibility
970 idl_constructor = interface.constructors[0]
971 constructor = constructor_context(interface, idl_constructor)
972 # FIXME(vsm): We drop the name. We don't use this in Dart APIs right now.
973 # We probably need to encode this somehow to deal with conflicts.
974 # constructor['name'] = extended_attributes['NamedConstructor']
975 return constructor
976
977
978 ################################################################################
979 # Special operations (methods)
980 # http://heycam.github.io/webidl/#idl-special-operations
981 ################################################################################
982
983 def property_getter(getter, cpp_arguments):
984 def is_null_expression(idl_type):
985 if idl_type.is_union_type:
986 return ' && '.join('!result%sEnabled' % i
987 for i, _ in enumerate(idl_type.member_types))
988 if idl_type.name == 'String':
989 # FIXME(vsm): This looks V8 specific.
990 return 'result.isNull()'
991 if idl_type.is_interface_type:
992 return '!result'
993 return ''
994
995 context = v8_interface.property_getter(getter, [])
996
997 idl_type = getter.idl_type
998 extended_attributes = getter.extended_attributes
999 is_raises_exception = 'RaisesException' in extended_attributes
1000
1001 # FIXME: make more generic, so can use dart_methods.cpp_value
1002 cpp_method_name = 'receiver->%s' % DartUtilities.cpp_name(getter)
1003
1004 if is_raises_exception:
1005 cpp_arguments.append('es')
1006 union_arguments = idl_type.union_arguments
1007 if union_arguments:
1008 cpp_arguments.extend([member_argument['cpp_value']
1009 for member_argument in union_arguments])
1010
1011 cpp_value = '%s(%s)' % (cpp_method_name, ', '.join(cpp_arguments))
1012
1013 context.update({
1014 'cpp_type': idl_type.cpp_type,
1015 'cpp_value': cpp_value,
1016 'is_null_expression': is_null_expression(idl_type),
1017 'is_raises_exception': is_raises_exception,
1018 'name': DartUtilities.cpp_name(getter),
1019 'union_arguments': union_arguments,
1020 'dart_set_return_value': idl_type.dart_set_return_value('result',
1021 extended_attribu tes=extended_attributes,
1022 script_wrappable ='receiver',
1023 release=idl_type .release)})
1024 return context
1025
1026
1027 def property_setter(setter):
1028 context = v8_interface.property_setter(setter)
1029
1030 idl_type = setter.arguments[1].idl_type
1031 extended_attributes = setter.extended_attributes
1032
1033 context.update({
1034 'dart_value_to_local_cpp_value': idl_type.dart_value_to_local_cpp_value(
1035 extended_attributes, 'propertyValue', False,
1036 context['has_type_checking_interface']),
1037 })
1038
1039 return context
1040
1041
1042 ################################################################################
1043 # Indexed properties
1044 # http://heycam.github.io/webidl/#idl-indexed-properties
1045 ################################################################################
1046
1047 def indexed_property_getter(interface):
1048 try:
1049 # Find indexed property getter, if present; has form:
1050 # getter TYPE [OPTIONAL_IDENTIFIER](unsigned long ARG1)
1051 getter = next(
1052 method
1053 for method in interface.operations
1054 if ('getter' in method.specials and
1055 len(method.arguments) == 1 and
1056 str(method.arguments[0].idl_type) == 'unsigned long'))
1057 except StopIteration:
1058 return None
1059
1060 getter.name = getter.name or 'anonymousIndexedGetter'
1061
1062 return property_getter(getter, ['index'])
1063
1064
1065 def indexed_property_setter(interface):
1066 try:
1067 # Find indexed property setter, if present; has form:
1068 # setter RETURN_TYPE [OPTIONAL_IDENTIFIER](unsigned long ARG1, ARG_TYPE ARG2)
1069 setter = next(
1070 method
1071 for method in interface.operations
1072 if ('setter' in method.specials and
1073 len(method.arguments) == 2 and
1074 str(method.arguments[0].idl_type) == 'unsigned long'))
1075 except StopIteration:
1076 return None
1077
1078 return property_setter(setter)
1079
1080
1081 ################################################################################
1082 # Named properties
1083 # http://heycam.github.io/webidl/#idl-named-properties
1084 ################################################################################
1085
1086 def named_property_getter(interface):
1087 try:
1088 # Find named property getter, if present; has form:
1089 # getter TYPE [OPTIONAL_IDENTIFIER](DOMString ARG1)
1090 getter = next(
1091 method
1092 for method in interface.operations
1093 if ('getter' in method.specials and
1094 len(method.arguments) == 1 and
1095 str(method.arguments[0].idl_type) == 'DOMString'))
1096 except StopIteration:
1097 return None
1098
1099 getter.name = getter.name or 'anonymousNamedGetter'
1100
1101 return property_getter(getter, ['propertyName'])
1102
1103
1104 def named_property_setter(interface):
1105 try:
1106 # Find named property setter, if present; has form:
1107 # setter RETURN_TYPE [OPTIONAL_IDENTIFIER](DOMString ARG1, ARG_TYPE ARG2 )
1108 setter = next(
1109 method
1110 for method in interface.operations
1111 if ('setter' in method.specials and
1112 len(method.arguments) == 2 and
1113 str(method.arguments[0].idl_type) == 'DOMString'))
1114 except StopIteration:
1115 return None
1116
1117 return property_setter(setter)
1118
1119
1120 def generate_native_entries_for_specials(interface, context):
1121 def add(prop, name, arity):
1122 if context[prop]:
1123 if 'native_entries' not in context[prop]:
1124 context[prop].update({'native_entries': []})
1125 context[prop]['native_entries'].append(
1126 DartUtilities.generate_native_entry(
1127 interface.name, name, 'Method', False, arity))
1128
1129 pre = ['indexed_property', 'named_property']
1130 post = [('setter', '__setter__', 2),
1131 ('getter', '__getter__', 1),
1132 ('deleter', '__delete__', 1),
1133 ]
1134 props = [(p1 + "_" + p2, name, arity)
1135 for (p1, (p2, name, arity)) in itertools.product(pre, post)]
1136 for t in props:
1137 add(*t)
1138
1139 for (p, name, arity) in props:
1140 if context[p]:
1141 if context[p].get('is_custom_property_query'):
1142 add(p, '__propertyQuery__', 1)
OLDNEW
« no previous file with comments | « bindings/dart/scripts/dart_dictionary.py ('k') | bindings/dart/scripts/dart_methods.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698