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