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 |