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