| 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 system to generate | 6 """This module provides shared functionality for the system to generate |
| 7 Dart:html APIs from the IDL database.""" | 7 Dart:html APIs from the IDL database.""" |
| 8 | 8 |
| 9 import emitter | 9 import emitter |
| 10 import os | 10 import os |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 template = self._template_loader.Load( | 500 template = self._template_loader.Load( |
| 501 template_file, | 501 template_file, |
| 502 {'DEFINE_CONTAINS': not has_contains}) | 502 {'DEFINE_CONTAINS': not has_contains}) |
| 503 self._members_emitter.Emit(template, E=self._DartType(element_type)) | 503 self._members_emitter.Emit(template, E=self._DartType(element_type)) |
| 504 | 504 |
| 505 def EmitAttribute(self, attribute, html_name, read_only): | 505 def EmitAttribute(self, attribute, html_name, read_only): |
| 506 if self._HasCustomImplementation(attribute.id): | 506 if self._HasCustomImplementation(attribute.id): |
| 507 return | 507 return |
| 508 | 508 |
| 509 if IsPureInterface(self._interface.id): | 509 if IsPureInterface(self._interface.id): |
| 510 self._AddInterfaceAttribute(attribute, html_name) | 510 self._AddInterfaceAttribute(attribute) |
| 511 return |
| 512 |
| 513 if attribute.id != html_name: |
| 514 self._AddAttributeUsingProperties(attribute, html_name, read_only) |
| 511 return | 515 return |
| 512 | 516 |
| 513 # If the attribute is shadowing, we can't generate a shadowing | 517 # If the attribute is shadowing, we can't generate a shadowing |
| 514 # field (Issue 1633). | 518 # field (Issue 1633). |
| 515 # TODO(sra): _FindShadowedAttribute does not take into account the html | 519 # TODO(sra): _FindShadowedAttribute does not take into account the html |
| 516 # renaming. we should be looking for another attribute that has the same | 520 # renaming. we should be looking for another attribute that has the same |
| 517 # html_name. Two attributes with the same IDL name might not match if one | 521 # html_name. Two attributes with the same IDL name might not match if one |
| 518 # is renamed. | 522 # is renamed. |
| 519 (super_attribute, super_attribute_interface) = self._FindShadowedAttribute( | 523 (super_attribute, super_attribute_interface) = self._FindShadowedAttribute( |
| 520 attribute) | 524 attribute) |
| 521 if super_attribute: | 525 if super_attribute: |
| 522 if read_only: | 526 if read_only: |
| 523 if attribute.type.id == super_attribute.type.id: | 527 if attribute.type.id == super_attribute.type.id: |
| 524 # Compatible attribute, use the superclass property. This works | 528 # Compatible attribute, use the superclass property. This works |
| 525 # because JavaScript will do its own dynamic dispatch. | 529 # because JavaScript will do its own dynamic dispatch. |
| 526 self._members_emitter.Emit( | 530 self._members_emitter.Emit( |
| 527 '\n' | 531 '\n' |
| 528 ' // Use implementation from $SUPER.\n' | 532 ' // Use implementation from $SUPER.\n' |
| 529 ' // final $TYPE $NAME;\n', | 533 ' // final $TYPE $NAME;\n', |
| 530 SUPER=super_attribute_interface, | 534 SUPER=super_attribute_interface, |
| 531 NAME=html_name, | 535 NAME=DartDomNameOfAttribute(attribute), |
| 532 TYPE=self.SecureOutputType(attribute.type.id)) | 536 TYPE=self.SecureOutputType(attribute.type.id)) |
| 533 return | 537 return |
| 534 self._members_emitter.Emit('\n // Shadowing definition.') | 538 self._members_emitter.Emit('\n // Shadowing definition.') |
| 535 self._AddAttributeUsingProperties(attribute, html_name, read_only) | 539 self._AddAttributeUsingProperties(attribute, html_name, read_only) |
| 536 return | 540 return |
| 537 | 541 |
| 538 # If the type has a conversion we need a getter or setter to contain the | 542 # If the type has a conversion we need a getter or setter to contain the |
| 539 # conversion code. | 543 # conversion code. |
| 540 if (self._OutputConversion(attribute.type.id, attribute.id) or | 544 if (self._OutputConversion(attribute.type.id, attribute.id) or |
| 541 self._InputConversion(attribute.type.id, attribute.id)): | 545 self._InputConversion(attribute.type.id, attribute.id)): |
| 542 self._AddAttributeUsingProperties(attribute, html_name, read_only) | 546 self._AddAttributeUsingProperties(attribute, html_name, read_only) |
| 543 return | 547 return |
| 544 | 548 |
| 545 output_type = self.SecureOutputType(attribute.type.id) | 549 output_type = self.SecureOutputType(attribute.type.id) |
| 546 input_type = self._NarrowInputType(attribute.type.id) | 550 input_type = self._NarrowInputType(attribute.type.id) |
| 547 annotations = self._Annotations(attribute.type.id, attribute.id) | 551 annotations = self._Annotations(attribute.type.id, attribute.id) |
| 548 rename = self._RenamingAnnotation(attribute.id, html_name) | |
| 549 self.EmitAttributeDocumentation(attribute) | 552 self.EmitAttributeDocumentation(attribute) |
| 550 if not read_only: | 553 if not read_only: |
| 551 self._members_emitter.Emit( | 554 self._members_emitter.Emit( |
| 552 '\n $RENAME$ANNOTATIONS$TYPE $NAME;' | 555 '\n $ANNOTATIONS$TYPE $NAME;' |
| 553 '\n', | 556 '\n', |
| 554 RENAME=rename, | |
| 555 ANNOTATIONS=annotations, | 557 ANNOTATIONS=annotations, |
| 556 NAME=html_name, | 558 NAME=DartDomNameOfAttribute(attribute), |
| 557 TYPE=output_type) | 559 TYPE=output_type) |
| 558 else: | 560 else: |
| 559 self._members_emitter.Emit( | 561 self._members_emitter.Emit( |
| 560 '\n $RENAME$(ANNOTATIONS)final $TYPE $NAME;' | 562 '\n $(ANNOTATIONS)final $TYPE $NAME;' |
| 561 '\n', | 563 '\n', |
| 562 RENAME=rename, | |
| 563 ANNOTATIONS=annotations, | 564 ANNOTATIONS=annotations, |
| 564 NAME=html_name, | 565 NAME=DartDomNameOfAttribute(attribute), |
| 565 TYPE=output_type) | 566 TYPE=output_type) |
| 566 | 567 |
| 567 def _AddAttributeUsingProperties(self, attribute, html_name, read_only): | 568 def _AddAttributeUsingProperties(self, attribute, html_name, read_only): |
| 568 self._AddRenamingGetter(attribute, html_name) | 569 self._AddRenamingGetter(attribute, html_name) |
| 569 if not read_only: | 570 if not read_only: |
| 570 self._AddRenamingSetter(attribute, html_name) | 571 self._AddRenamingSetter(attribute, html_name) |
| 571 | 572 |
| 572 def _AddInterfaceAttribute(self, attribute, html_name): | 573 def _AddInterfaceAttribute(self, attribute): |
| 573 self._members_emitter.Emit( | 574 self._members_emitter.Emit( |
| 574 '\n $TYPE $NAME;' | 575 '\n $TYPE $NAME;' |
| 575 '\n', | 576 '\n', |
| 576 NAME=html_name, | 577 NAME=DartDomNameOfAttribute(attribute), |
| 577 TYPE=self.SecureOutputType(attribute.type.id)) | 578 TYPE=self.SecureOutputType(attribute.type.id)) |
| 578 | 579 |
| 579 def _AddRenamingGetter(self, attr, html_name): | 580 def _AddRenamingGetter(self, attr, html_name): |
| 580 self.EmitAttributeDocumentation(attr) | 581 self.EmitAttributeDocumentation(attr) |
| 581 | 582 |
| 582 conversion = self._OutputConversion(attr.type.id, attr.id) | 583 conversion = self._OutputConversion(attr.type.id, attr.id) |
| 583 if conversion: | 584 if conversion: |
| 584 return self._AddConvertingGetter(attr, html_name, conversion) | 585 return self._AddConvertingGetter(attr, html_name, conversion) |
| 585 return_type = self.SecureOutputType(attr.type.id) | 586 return_type = self.SecureOutputType(attr.type.id) |
| 586 native_type = self._NarrowToImplementationType(attr.type.id) | 587 native_type = self._NarrowToImplementationType(attr.type.id) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 604 '\n void set $HTML_NAME($TYPE value) {' | 605 '\n void set $HTML_NAME($TYPE value) {' |
| 605 '\n JS("void", "#.$NAME = #", this, value);' | 606 '\n JS("void", "#.$NAME = #", this, value);' |
| 606 '\n }' | 607 '\n }' |
| 607 '\n', | 608 '\n', |
| 608 HTML_NAME=html_name, | 609 HTML_NAME=html_name, |
| 609 NAME=attr.id, | 610 NAME=attr.id, |
| 610 TYPE=self._NarrowInputType(attr.type.id)) | 611 TYPE=self._NarrowInputType(attr.type.id)) |
| 611 | 612 |
| 612 def _AddConvertingGetter(self, attr, html_name, conversion): | 613 def _AddConvertingGetter(self, attr, html_name, conversion): |
| 613 self._members_emitter.Emit( | 614 self._members_emitter.Emit( |
| 615 # TODO(sra): Use metadata to provide native name. |
| 614 '\n $RETURN_TYPE get $HTML_NAME => $CONVERT(this._$(HTML_NAME));' | 616 '\n $RETURN_TYPE get $HTML_NAME => $CONVERT(this._$(HTML_NAME));' |
| 615 "\n @JSName('$NAME')" | 617 '\n $NATIVE_TYPE get _$HTML_NAME =>' |
| 616 '\n $(ANNOTATIONS)final $NATIVE_TYPE _$HTML_NAME;' | 618 ' JS("$NATIVE_TYPE", "#.$NAME", this);' |
| 617 '\n', | 619 '\n', |
| 618 ANNOTATIONS=self._Annotations(attr.type.id, html_name), | |
| 619 CONVERT=conversion.function_name, | 620 CONVERT=conversion.function_name, |
| 620 HTML_NAME=html_name, | 621 HTML_NAME=html_name, |
| 621 NAME=attr.id, | 622 NAME=attr.id, |
| 622 RETURN_TYPE=conversion.output_type, | 623 RETURN_TYPE=conversion.output_type, |
| 623 NATIVE_TYPE=conversion.input_type) | 624 NATIVE_TYPE=conversion.input_type) |
| 624 | 625 |
| 625 def _AddConvertingSetter(self, attr, html_name, conversion): | 626 def _AddConvertingSetter(self, attr, html_name, conversion): |
| 626 self._members_emitter.Emit( | 627 self._members_emitter.Emit( |
| 627 # TODO(sra): Use metadata to provide native name. | 628 # TODO(sra): Use metadata to provide native name. |
| 628 '\n void set $HTML_NAME($INPUT_TYPE value) {' | 629 '\n void set $HTML_NAME($INPUT_TYPE value) {' |
| (...skipping 24 matching lines...) Expand all Loading... |
| 653 | 654 |
| 654 if IsPureInterface(self._interface.id): | 655 if IsPureInterface(self._interface.id): |
| 655 self._AddInterfaceOperation(info, html_name) | 656 self._AddInterfaceOperation(info, html_name) |
| 656 elif any(self._OperationRequiresConversions(op) for op in info.overloads): | 657 elif any(self._OperationRequiresConversions(op) for op in info.overloads): |
| 657 # Any conversions needed? | 658 # Any conversions needed? |
| 658 self._AddOperationWithConversions(info, html_name) | 659 self._AddOperationWithConversions(info, html_name) |
| 659 else: | 660 else: |
| 660 self._AddDirectNativeOperation(info, html_name) | 661 self._AddDirectNativeOperation(info, html_name) |
| 661 | 662 |
| 662 def _AddDirectNativeOperation(self, info, html_name): | 663 def _AddDirectNativeOperation(self, info, html_name): |
| 663 self._members_emitter.Emit( | 664 # Do we need a native body? |
| 664 '\n' | 665 if html_name != info.declared_name: |
| 665 ' $RENAME$ANNOTATIONS$MODIFIERS$TYPE $NAME($PARAMS) native;\n', | 666 return_type = self.SecureOutputType(info.type_name) |
| 666 RENAME=self._RenamingAnnotation(info.declared_name, html_name), | 667 |
| 667 ANNOTATIONS=self._Annotations(info.type_name, info.declared_name), | 668 operation_emitter = self._members_emitter.Emit( |
| 668 MODIFIERS='static ' if info.IsStatic() else '', | 669 '$!SCOPE', |
| 669 TYPE=self.SecureOutputType(info.type_name), | 670 MODIFIERS='static ' if info.IsStatic() else '', |
| 670 NAME=html_name, | 671 ANNOTATIONS=self._Annotations(info.type_name, info.declared_name), |
| 671 PARAMS=info.ParametersDeclaration(self._NarrowInputType)) | 672 TYPE=return_type, |
| 673 HTML_NAME=html_name, |
| 674 NAME=info.declared_name, |
| 675 PARAMS=info.ParametersDeclaration(self._NarrowInputType)) |
| 676 |
| 677 operation_emitter.Emit( |
| 678 '\n' |
| 679 ' $ANNOTATIONS' |
| 680 '$MODIFIERS$TYPE $(HTML_NAME)($PARAMS) native "$NAME";\n') |
| 681 else: |
| 682 self._members_emitter.Emit( |
| 683 '\n' |
| 684 ' $ANNOTATIONS$MODIFIERS$TYPE $NAME($PARAMS) native;\n', |
| 685 MODIFIERS='static ' if info.IsStatic() else '', |
| 686 ANNOTATIONS=self._Annotations(info.type_name, info.declared_name), |
| 687 TYPE=self.SecureOutputType(info.type_name), |
| 688 NAME=info.name, |
| 689 PARAMS=info.ParametersDeclaration(self._NarrowInputType)) |
| 672 | 690 |
| 673 def _AddOperationWithConversions(self, info, html_name): | 691 def _AddOperationWithConversions(self, info, html_name): |
| 674 # Assert all operations have same return type. | 692 # Assert all operations have same return type. |
| 675 assert len(set([op.type.id for op in info.operations])) == 1 | 693 assert len(set([op.type.id for op in info.operations])) == 1 |
| 676 output_conversion = self._OutputConversion(info.type_name, | 694 output_conversion = self._OutputConversion(info.type_name, |
| 677 info.declared_name) | 695 info.declared_name) |
| 678 if output_conversion: | 696 if output_conversion: |
| 679 return_type = output_conversion.output_type | 697 return_type = output_conversion.output_type |
| 680 native_return_type = output_conversion.input_type | 698 native_return_type = output_conversion.input_type |
| 681 else: | 699 else: |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 760 if output_conversion: | 778 if output_conversion: |
| 761 call = '%s(%s)' % (output_conversion.function_name, call) | 779 call = '%s(%s)' % (output_conversion.function_name, call) |
| 762 | 780 |
| 763 if operation.type.id == 'void': | 781 if operation.type.id == 'void': |
| 764 call_emitter.Emit('$(INDENT)$CALL;\n$(INDENT)return;\n', | 782 call_emitter.Emit('$(INDENT)$CALL;\n$(INDENT)return;\n', |
| 765 CALL=call) | 783 CALL=call) |
| 766 else: | 784 else: |
| 767 call_emitter.Emit('$(INDENT)return $CALL;\n', CALL=call) | 785 call_emitter.Emit('$(INDENT)return $CALL;\n', CALL=call) |
| 768 | 786 |
| 769 self._members_emitter.Emit( | 787 self._members_emitter.Emit( |
| 770 ' $RENAME$ANNOTATIONS$MODIFIERS$TYPE$TARGET($PARAMS) native;\n', | 788 ' $MODIFIERS$ANNOTATIONS$TYPE$TARGET($PARAMS) native "$NATIVE";\n', |
| 771 RENAME=self._RenamingAnnotation(info.declared_name, target), | 789 MODIFIERS='static ' if info.IsStatic() else '', |
| 772 ANNOTATIONS=self._Annotations(info.type_name, info.declared_name), | 790 ANNOTATIONS=self._Annotations(info.type_name, info.declared_name), |
| 773 MODIFIERS='static ' if info.IsStatic() else '', | |
| 774 TYPE=TypeOrNothing(native_return_type), | 791 TYPE=TypeOrNothing(native_return_type), |
| 775 TARGET=target, | 792 TARGET=target, |
| 776 PARAMS=', '.join(target_parameters)) | 793 PARAMS=', '.join(target_parameters), |
| 794 NATIVE=info.declared_name) |
| 777 | 795 |
| 778 def GenerateChecksAndCall(operation, argument_count): | 796 def GenerateChecksAndCall(operation, argument_count): |
| 779 checks = [] | 797 checks = [] |
| 780 for i in range(0, argument_count): | 798 for i in range(0, argument_count): |
| 781 argument = operation.arguments[i] | 799 argument = operation.arguments[i] |
| 782 parameter_name = parameter_names[i] | 800 parameter_name = parameter_names[i] |
| 783 test_type = self._DartType(argument.type.id) | 801 test_type = self._DartType(argument.type.id) |
| 784 if test_type in ['dynamic', 'Object']: | 802 if test_type in ['dynamic', 'Object']: |
| 785 checks.append('?%s' % parameter_name) | 803 checks.append('?%s' % parameter_name) |
| 786 elif test_type != parameter_types[i]: | 804 elif test_type != parameter_types[i]: |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 846 return FindConversion(idl_type, 'get', self._interface.id, member) | 864 return FindConversion(idl_type, 'get', self._interface.id, member) |
| 847 | 865 |
| 848 def _InputConversion(self, idl_type, member): | 866 def _InputConversion(self, idl_type, member): |
| 849 return FindConversion(idl_type, 'set', self._interface.id, member) | 867 return FindConversion(idl_type, 'set', self._interface.id, member) |
| 850 | 868 |
| 851 def _HasCustomImplementation(self, member_name): | 869 def _HasCustomImplementation(self, member_name): |
| 852 member_name = '%s.%s' % (self._interface_type_info.interface_name(), | 870 member_name = '%s.%s' % (self._interface_type_info.interface_name(), |
| 853 member_name) | 871 member_name) |
| 854 return member_name in _js_custom_members | 872 return member_name in _js_custom_members |
| 855 | 873 |
| 856 def _RenamingAnnotation(self, idl_name, member_name): | 874 def _Annotations(self, idl_type, member_name): |
| 857 if member_name != idl_name: | 875 annotations = FindAnnotations(idl_type, self._interface.id, member_name) |
| 858 return "@JSName('%s')\n " % idl_name | |
| 859 return '' | |
| 860 | |
| 861 def _Annotations(self, idl_type, idl_member_name): | |
| 862 annotations = FindAnnotations(idl_type, self._interface.id, idl_member_name) | |
| 863 if annotations: | 876 if annotations: |
| 864 return '%s\n ' % annotations | 877 return '%s\n ' % annotations |
| 865 return_type = self.SecureOutputType(idl_type) | 878 return_type = self.SecureOutputType(idl_type) |
| 866 native_type = self._NarrowToImplementationType(idl_type) | 879 native_type = self._NarrowToImplementationType(idl_type) |
| 867 if native_type != return_type: | 880 if native_type != return_type: |
| 868 return "@Returns('%s') @Creates('%s')\n " % (native_type, native_type) | 881 return "@Returns('%s') @Creates('%s')\n " % (native_type, native_type) |
| 869 else: | 882 else: |
| 870 return '' | 883 return '' |
| 871 | 884 |
| 872 def CustomJSMembers(self): | 885 def CustomJSMembers(self): |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 977 'svg': DartLibrary('svg', template_loader, library_type, output_dir), | 990 'svg': DartLibrary('svg', template_loader, library_type, output_dir), |
| 978 'html': DartLibrary('html', template_loader, library_type, output_dir), | 991 'html': DartLibrary('html', template_loader, library_type, output_dir), |
| 979 } | 992 } |
| 980 | 993 |
| 981 def AddFile(self, basename, library_name, path): | 994 def AddFile(self, basename, library_name, path): |
| 982 self._libraries[library_name].AddFile(path) | 995 self._libraries[library_name].AddFile(path) |
| 983 | 996 |
| 984 def Emit(self, emitter, auxiliary_dir): | 997 def Emit(self, emitter, auxiliary_dir): |
| 985 for lib in self._libraries.values(): | 998 for lib in self._libraries.values(): |
| 986 lib.Emit(emitter, auxiliary_dir) | 999 lib.Emit(emitter, auxiliary_dir) |
| OLD | NEW |