OLD | NEW |
---|---|
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
3 # for details. All rights reserved. Use of this source code is governed by a | 3 # for details. All rights reserved. Use of this source code is governed by a |
4 # BSD-style license that can be found in the LICENSE file. | 4 # BSD-style license that can be found in the LICENSE file. |
5 | 5 |
6 """This module provides shared functionality for the systems to generate | 6 """This module provides shared functionality for the systems to generate |
7 native binding from the IDL database.""" | 7 native binding from the IDL database.""" |
8 | 8 |
9 import emitter | 9 import emitter |
10 import os | 10 import os |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
297 parameter_definitions = ( | 297 parameter_definitions = ( |
298 ' ScriptExecutionContext* context = DartUtilities::scriptExec utionContext();\n' | 298 ' ScriptExecutionContext* context = DartUtilities::scriptExec utionContext();\n' |
299 ' if (!context) {\n' | 299 ' if (!context) {\n' |
300 ' exception = Dart_NewString("Failed to create an object" );\n' | 300 ' exception = Dart_NewString("Failed to create an object" );\n' |
301 ' goto fail;\n' | 301 ' goto fail;\n' |
302 ' }\n') | 302 ' }\n') |
303 arguments = ['context'] | 303 arguments = ['context'] |
304 else: | 304 else: |
305 raise Exception('Unsupported CallWith=%s attribute' % call_with) | 305 raise Exception('Unsupported CallWith=%s attribute' % call_with) |
306 | 306 |
307 if raises_dom_exceptions: | |
308 arguments.append('ec') | |
309 | |
310 invocation = '%s::create(%s)' % (type_info.native_type(), ', '.join(argument s)) | |
307 self._GenerateNativeCallback( | 311 self._GenerateNativeCallback( |
308 callback_name='constructorCallback', | 312 callback_name='constructorCallback', |
309 idl_node=self._interface, | 313 idl_node=self._interface, |
310 parameter_definitions=parameter_definitions, | 314 parameter_definitions=parameter_definitions, |
311 needs_receiver=False, function_name='%s::create' % type_info.native_type (), | 315 needs_receiver=False, |
312 arguments=arguments, | 316 invocation=invocation, |
313 idl_return_type=self._interface, | 317 idl_return_type=self._interface, |
314 raises_dart_exceptions=raises_dart_exceptions, | 318 raises_dart_exceptions=raises_dart_exceptions, |
315 raises_dom_exceptions=raises_dom_exceptions) | 319 raises_dom_exceptions=raises_dom_exceptions) |
316 | 320 |
317 | |
318 def _ImplClassName(self, interface_name): | 321 def _ImplClassName(self, interface_name): |
319 return interface_name + 'Implementation' | 322 return interface_name + 'Implementation' |
320 | 323 |
321 def _IsConstructable(self): | 324 def _IsConstructable(self): |
322 # FIXME: support ConstructorTemplate. | 325 # FIXME: support ConstructorTemplate. |
323 return set(['CustomConstructor', 'V8CustomConstructor', 'Constructor']) & se t(self._interface.ext_attrs) | 326 return set(['CustomConstructor', 'V8CustomConstructor', 'Constructor']) & se t(self._interface.ext_attrs) |
324 | 327 |
325 def FinishInterface(self): | 328 def FinishInterface(self): |
326 base = self._BaseClassName(self._interface) | 329 base = self._BaseClassName(self._interface) |
327 self._dart_impl_emitter.Emit( | 330 self._dart_impl_emitter.Emit( |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
375 DECLARATIONS=self._cpp_declarations_emitter.Fragments()) | 378 DECLARATIONS=self._cpp_declarations_emitter.Fragments()) |
376 | 379 |
377 def AddAttribute(self, getter, setter): | 380 def AddAttribute(self, getter, setter): |
378 # FIXME: Dartium does not support attribute event listeners. However, JS | 381 # FIXME: Dartium does not support attribute event listeners. However, JS |
379 # implementation falls back to them when addEventListener is not available. | 382 # implementation falls back to them when addEventListener is not available. |
380 # Make sure addEventListener is available in all EventTargets and remove | 383 # Make sure addEventListener is available in all EventTargets and remove |
381 # this check. | 384 # this check. |
382 if (getter or setter).type.id == 'EventListener': | 385 if (getter or setter).type.id == 'EventListener': |
383 return | 386 return |
384 | 387 |
385 # FIXME: support 'ImplementedBy'. | |
386 if 'ImplementedBy' in (getter or setter).ext_attrs: | |
387 return | |
388 | |
389 # FIXME: these should go away. | 388 # FIXME: these should go away. |
390 classes_with_unsupported_custom_getters = [ | 389 classes_with_unsupported_custom_getters = [ |
391 'Clipboard', 'Console', 'Coordinates', 'DeviceMotionEvent', | 390 'Clipboard', 'Console', 'Coordinates', 'DeviceMotionEvent', |
392 'DeviceOrientationEvent', 'FileReader', 'JavaScriptCallFrame', | 391 'DeviceOrientationEvent', 'FileReader', 'JavaScriptCallFrame', |
393 'HTMLInputElement', 'HTMLOptionsCollection', 'HTMLOutputElement', | 392 'HTMLInputElement', 'HTMLOptionsCollection', 'HTMLOutputElement', |
394 'ScriptProfileNode', 'WebKitAnimation'] | 393 'ScriptProfileNode', 'WebKitAnimation'] |
395 if (self._interface.id in classes_with_unsupported_custom_getters and | 394 if (self._interface.id in classes_with_unsupported_custom_getters and |
396 getter and set(['Custom', 'CustomGetter']) & set(getter.ext_attrs)): | 395 getter and set(['Custom', 'CustomGetter']) & set(getter.ext_attrs)): |
397 return | 396 return |
398 | 397 |
(...skipping 27 matching lines...) Expand all Loading... | |
426 else: | 425 else: |
427 webcore_function_name = re.sub(r'^(HTML|URL|JS|XML|XSLT|\w)', | 426 webcore_function_name = re.sub(r'^(HTML|URL|JS|XML|XSLT|\w)', |
428 lambda s: s.group(1).lower(), | 427 lambda s: s.group(1).lower(), |
429 attr.id) | 428 attr.id) |
430 webcore_function_name = re.sub(r'^(create|exclusive)', | 429 webcore_function_name = re.sub(r'^(create|exclusive)', |
431 lambda s: 'is' + s.group(1).capitalize(), | 430 lambda s: 'is' + s.group(1).capitalize(), |
432 webcore_function_name) | 431 webcore_function_name) |
433 if attr.type.id.startswith('SVGAnimated'): | 432 if attr.type.id.startswith('SVGAnimated'): |
434 webcore_function_name += 'Animated' | 433 webcore_function_name += 'Animated' |
435 | 434 |
435 invocation = self._GenerateWebCoreInvocation(attr, webcore_function_name, | |
436 arguments, attr.get_raises) | |
436 self._GenerateNativeCallback(cpp_callback_name, attr, '', | 437 self._GenerateNativeCallback(cpp_callback_name, attr, '', |
437 True, webcore_function_name, arguments, idl_return_type=attr.type, | 438 True, invocation, idl_return_type=attr.type, |
438 raises_dart_exceptions=attr.get_raises, | 439 raises_dart_exceptions=attr.get_raises, |
439 raises_dom_exceptions=attr.get_raises) | 440 raises_dom_exceptions=attr.get_raises) |
440 | 441 |
441 def _AddSetter(self, attr): | 442 def _AddSetter(self, attr): |
442 dart_declaration = 'void set %s(%s)' % (attr.id, attr.type.id) | 443 dart_declaration = 'void set %s(%s)' % (attr.id, attr.type.id) |
443 is_custom = set(['Custom', 'CustomSetter', 'V8CustomSetter']) & set(attr.ext _attrs) | 444 is_custom = set(['Custom', 'CustomSetter', 'V8CustomSetter']) & set(attr.ext _attrs) |
444 cpp_callback_name = self._GenerateNativeBinding(attr.id, 2, | 445 cpp_callback_name = self._GenerateNativeBinding(attr.id, 2, |
445 dart_declaration, 'Setter', is_custom) | 446 dart_declaration, 'Setter', is_custom) |
446 if is_custom: | 447 if is_custom: |
447 return | 448 return |
448 | 449 |
449 arguments = [] | 450 arguments = [] |
450 if 'Reflect' in attr.ext_attrs: | 451 if 'Reflect' in attr.ext_attrs: |
451 webcore_function_name = GetIDLTypeInfo(attr.type).webcore_setter_name() | 452 webcore_function_name = GetIDLTypeInfo(attr.type).webcore_setter_name() |
452 arguments.append(self._GenerateWebCoreReflectionAttributeName(attr)) | 453 arguments.append(self._GenerateWebCoreReflectionAttributeName(attr)) |
453 else: | 454 else: |
454 webcore_function_name = re.sub(r'^(xml(?=[A-Z])|\w)', | 455 webcore_function_name = re.sub(r'^(xml(?=[A-Z])|\w)', |
455 lambda s: s.group(1).upper(), | 456 lambda s: s.group(1).upper(), |
456 attr.id) | 457 attr.id) |
457 webcore_function_name = 'set%s' % webcore_function_name | 458 webcore_function_name = 'set%s' % webcore_function_name |
458 if attr.type.id.startswith('SVGAnimated'): | 459 if attr.type.id.startswith('SVGAnimated'): |
459 webcore_function_name += 'Animated' | 460 webcore_function_name += 'Animated' |
460 | 461 |
461 arguments.append(attr.id) | 462 arguments.append(attr.id) |
463 | |
462 parameter_definitions_emitter = emitter.Emitter() | 464 parameter_definitions_emitter = emitter.Emitter() |
463 self._GenerateParameterAdapter(parameter_definitions_emitter, attr, 0) | 465 self._GenerateParameterAdapter(parameter_definitions_emitter, attr, 0) |
464 parameter_definitions = parameter_definitions_emitter.Fragments() | 466 parameter_definitions = parameter_definitions_emitter.Fragments() |
467 invocation = self._GenerateWebCoreInvocation(attr, webcore_function_name, | |
468 arguments, attr.set_raises) | |
465 self._GenerateNativeCallback(cpp_callback_name, attr, parameter_definitions, | 469 self._GenerateNativeCallback(cpp_callback_name, attr, parameter_definitions, |
466 True, webcore_function_name, arguments, idl_return_type=None, | 470 True, invocation, idl_return_type=None, |
467 raises_dart_exceptions=True, | 471 raises_dart_exceptions=True, |
468 raises_dom_exceptions=attr.set_raises) | 472 raises_dom_exceptions=attr.set_raises) |
469 | 473 |
470 def _HasNativeIndexGetter(self, interface): | 474 def _HasNativeIndexGetter(self, interface): |
471 return ('CustomIndexedGetter' in interface.ext_attrs or | 475 return ('CustomIndexedGetter' in interface.ext_attrs or |
472 'NumericIndexedGetter' in interface.ext_attrs) | 476 'NumericIndexedGetter' in interface.ext_attrs) |
473 | 477 |
474 def _EmitNativeIndexGetter(self, interface, element_type): | 478 def _EmitNativeIndexGetter(self, interface, element_type): |
475 dart_declaration = '%s operator[](int index)' % element_type | 479 dart_declaration = '%s operator[](int index)' % element_type |
476 self._GenerateNativeBinding('numericIndexGetter', 2, dart_declaration, | 480 self._GenerateNativeBinding('numericIndexGetter', 2, dart_declaration, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
516 def GenerateSingleOperation(self, dispatch_emitter, info, indent, operation): | 520 def GenerateSingleOperation(self, dispatch_emitter, info, indent, operation): |
517 """Generates a call to a single operation. | 521 """Generates a call to a single operation. |
518 | 522 |
519 Arguments: | 523 Arguments: |
520 dispatch_emitter: an dispatch_emitter for the body of a block of code. | 524 dispatch_emitter: an dispatch_emitter for the body of a block of code. |
521 info: the compound information about the operation and its overloads. | 525 info: the compound information about the operation and its overloads. |
522 indent: an indentation string for generated code. | 526 indent: an indentation string for generated code. |
523 operation: the IDLOperation to call. | 527 operation: the IDLOperation to call. |
524 """ | 528 """ |
525 | 529 |
526 # FIXME: support ImplementedBy callbacks. | |
527 if 'ImplementedBy' in operation.ext_attrs: | |
528 return | |
529 | |
530 for op in self._interface.operations: | 530 for op in self._interface.operations: |
531 if op.id != operation.id or len(op.arguments) <= len(operation.arguments): | 531 if op.id != operation.id or len(op.arguments) <= len(operation.arguments): |
532 continue | 532 continue |
533 next_argument = op.arguments[len(operation.arguments)] | 533 next_argument = op.arguments[len(operation.arguments)] |
534 if next_argument.is_optional and 'Callback' in next_argument.ext_attrs: | 534 if next_argument.is_optional and 'Callback' in next_argument.ext_attrs: |
535 # FIXME: '[Optional, Callback]' arguments could be non-optional in | 535 # FIXME: '[Optional, Callback]' arguments could be non-optional in |
536 # webcore. We need to fix overloads handling to generate native | 536 # webcore. We need to fix overloads handling to generate native |
537 # callbacks properly. | 537 # callbacks properly. |
538 return | 538 return |
539 | 539 |
(...skipping 20 matching lines...) Expand all Loading... | |
560 dart_declaration = '%s _%s(%s)' % (info.type_name, native_name, | 560 dart_declaration = '%s _%s(%s)' % (info.type_name, native_name, |
561 argument_list) | 561 argument_list) |
562 is_custom = 'Custom' in operation.ext_attrs | 562 is_custom = 'Custom' in operation.ext_attrs |
563 cpp_callback_name = self._GenerateNativeBinding( | 563 cpp_callback_name = self._GenerateNativeBinding( |
564 native_name, 1 + len(operation.arguments), dart_declaration, 'Callback', | 564 native_name, 1 + len(operation.arguments), dart_declaration, 'Callback', |
565 is_custom) | 565 is_custom) |
566 if is_custom: | 566 if is_custom: |
567 return | 567 return |
568 | 568 |
569 # Generate callback. | 569 # Generate callback. |
570 webcore_function_name = operation.id | 570 webcore_function_name = operation.ext_attrs.get('ImplementedAs', operation.i d) |
571 if 'ImplementedAs' in operation.ext_attrs: | |
572 webcore_function_name = operation.ext_attrs['ImplementedAs'] | |
573 | 571 |
574 parameter_definitions_emitter = emitter.Emitter() | 572 parameter_definitions_emitter = emitter.Emitter() |
575 raises_dart_exceptions = len(operation.arguments) > 0 or operation.raises | 573 raises_dart_exceptions = len(operation.arguments) > 0 or operation.raises |
576 arguments = [] | 574 arguments = [] |
577 | 575 |
578 # Process 'CallWith' argument. | 576 # Process 'CallWith' argument. |
579 if 'CallWith' in operation.ext_attrs: | 577 if 'CallWith' in operation.ext_attrs: |
580 call_with = operation.ext_attrs['CallWith'] | 578 call_with = operation.ext_attrs['CallWith'] |
581 if call_with == 'ScriptExecutionContext': | 579 if call_with == 'ScriptExecutionContext': |
582 parameter_definitions_emitter.Emit( | 580 parameter_definitions_emitter.Emit( |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
618 if len(operation.arguments) == 2: | 616 if len(operation.arguments) == 2: |
619 arguments.append('false') | 617 arguments.append('false') |
620 | 618 |
621 if self._interface.id == 'CSSStyleDeclaration' and operation.id == 'setPrope rty': | 619 if self._interface.id == 'CSSStyleDeclaration' and operation.id == 'setPrope rty': |
622 # CSSStyleDeclaration.setProperty priority parameter is optional in Dart | 620 # CSSStyleDeclaration.setProperty priority parameter is optional in Dart |
623 # idl, but is not optional in webcore implementation. | 621 # idl, but is not optional in webcore implementation. |
624 if len(operation.arguments) == 2: | 622 if len(operation.arguments) == 2: |
625 arguments.append('String()') | 623 arguments.append('String()') |
626 | 624 |
627 if 'NeedsUserGestureCheck' in operation.ext_attrs: | 625 if 'NeedsUserGestureCheck' in operation.ext_attrs: |
628 arguments.extend('DartUtilities::processingUserGesture') | 626 arguments.append('DartUtilities::processingUserGesture') |
629 | 627 |
630 parameter_definitions = parameter_definitions_emitter.Fragments() | 628 invocation = self._GenerateWebCoreInvocation(operation, |
631 self._GenerateNativeCallback(cpp_callback_name, operation, parameter_definit ions, | 629 webcore_function_name, arguments, operation.raises) |
632 True, webcore_function_name, arguments, idl_return_type=operation.type, | 630 self._GenerateNativeCallback(cpp_callback_name, operation, |
631 parameter_definitions=parameter_definitions_emitter.Fragments(), | |
632 needs_receiver=True, invocation=invocation, | |
633 idl_return_type=operation.type, | |
633 raises_dart_exceptions=raises_dart_exceptions, | 634 raises_dart_exceptions=raises_dart_exceptions, |
634 raises_dom_exceptions=operation.raises) | 635 raises_dom_exceptions=operation.raises) |
635 | 636 |
636 def _GenerateNativeCallback(self, callback_name, idl_node, | 637 def _GenerateNativeCallback(self, callback_name, idl_node, |
637 parameter_definitions, needs_receiver, function_name, arguments, idl_retur n_type, | 638 parameter_definitions, needs_receiver, invocation, idl_return_type, |
638 raises_dart_exceptions, raises_dom_exceptions): | 639 raises_dart_exceptions, raises_dom_exceptions): |
639 if raises_dom_exceptions: | 640 |
640 arguments.append('ec') | 641 callback = invocation |
641 prefix = '' | |
642 if needs_receiver: prefix = self._interface_type_info.receiver() | |
643 callback = '%s%s(%s)' % (prefix, function_name, ', '.join(arguments)) | |
644 | 642 |
645 nested_templates = [] | 643 nested_templates = [] |
646 if idl_return_type and idl_return_type.id != 'void': | 644 if idl_return_type and idl_return_type.id != 'void': |
647 return_type_info = GetIDLTypeInfo(idl_return_type) | 645 return_type_info = GetIDLTypeInfo(idl_return_type) |
648 conversion_cast = return_type_info.conversion_cast('$BODY') | 646 conversion_cast = return_type_info.conversion_cast('$BODY') |
649 if isinstance(return_type_info, SVGTearOffIDLTypeInfo): | 647 if isinstance(return_type_info, SVGTearOffIDLTypeInfo): |
650 svg_primitive_types = ['SVGAngle', 'SVGLength', 'SVGMatrix', | 648 svg_primitive_types = ['SVGAngle', 'SVGLength', 'SVGMatrix', |
651 'SVGNumber', 'SVGPoint', 'SVGRect', 'SVGTransform'] | 649 'SVGNumber', 'SVGPoint', 'SVGRect', 'SVGTransform'] |
652 conversion_cast = '%s::create($BODY)' | 650 conversion_cast = '%s::create($BODY)' |
653 if self._interface.id.startswith('SVGAnimated'): | 651 if self._interface.id.startswith('SVGAnimated'): |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
774 namespace = 'HTMLNames' | 772 namespace = 'HTMLNames' |
775 svg_exceptions = ['class', 'id', 'onabort', 'onclick', 'onerror', 'onload', | 773 svg_exceptions = ['class', 'id', 'onabort', 'onclick', 'onerror', 'onload', |
776 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', | 774 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', |
777 'onmouseup', 'onresize', 'onscroll', 'onunload'] | 775 'onmouseup', 'onresize', 'onscroll', 'onunload'] |
778 if self._interface.id.startswith('SVG') and not attr.id in svg_exceptions: | 776 if self._interface.id.startswith('SVG') and not attr.id in svg_exceptions: |
779 namespace = 'SVGNames' | 777 namespace = 'SVGNames' |
780 self._cpp_impl_includes[namespace] = 1 | 778 self._cpp_impl_includes[namespace] = 1 |
781 | 779 |
782 attribute_name = attr.ext_attrs['Reflect'] or attr.id.lower() | 780 attribute_name = attr.ext_attrs['Reflect'] or attr.id.lower() |
783 return 'WebCore::%s::%sAttr' % (namespace, attribute_name) | 781 return 'WebCore::%s::%sAttr' % (namespace, attribute_name) |
782 | |
783 def _GenerateWebCoreInvocation(self, idl_node, function_name, arguments, | |
784 raises_dom_exceptions): | |
antonm
2012/02/24 19:01:40
I don't like how ec handling is now spread all ove
| |
785 if 'ImplementedBy' in idl_node.ext_attrs: | |
786 implementedBy = idl_node.ext_attrs['ImplementedBy'] | |
787 self._cpp_impl_includes[implementedBy] = 1 | |
788 invocation = '%s::%s' % (implementedBy, function_name) | |
789 arguments.insert(0, 'receiver') | |
790 else: | |
791 invocation = '%s%s' % (self._interface_type_info.receiver(), function_name ) | |
792 | |
793 if raises_dom_exceptions: | |
794 arguments.append('ec') | |
795 | |
796 return '%s(%s)' % (invocation, ', '.join(arguments)) | |
OLD | NEW |