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