| 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 | 10 |
| (...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 inits = emitter.Emit( | 582 inits = emitter.Emit( |
| 583 '\n' | 583 '\n' |
| 584 ' factory $CONSTRUCTOR($PARAMS) {\n' | 584 ' factory $CONSTRUCTOR($PARAMS) {\n' |
| 585 ' $CLASS _e = _document.$dom_createElement("$TAG");\n' | 585 ' $CLASS _e = _document.$dom_createElement("$TAG");\n' |
| 586 '$!INITS' | 586 '$!INITS' |
| 587 ' return _e;\n' | 587 ' return _e;\n' |
| 588 ' }\n', | 588 ' }\n', |
| 589 CONSTRUCTOR=constructor_info.ConstructorFullName(), | 589 CONSTRUCTOR=constructor_info.ConstructorFullName(), |
| 590 CLASS=class_name, | 590 CLASS=class_name, |
| 591 TAG=info.tag, | 591 TAG=info.tag, |
| 592 PARAMS=constructor_info.ParametersInterfaceDeclaration()) | 592 PARAMS=constructor_info.ParametersInterfaceDeclaration(DartType)) |
| 593 for param in constructor_info.param_infos: | 593 for param in constructor_info.param_infos: |
| 594 inits.Emit(' if ($E != null) _e.$E = $E;\n', E=param.name) | 594 inits.Emit(' if ($E != null) _e.$E = $E;\n', E=param.name) |
| 595 | 595 |
| 596 | 596 |
| 597 # These classes require an explicit declaration for the "on" method even though | 597 # These classes require an explicit declaration for the "on" method even though |
| 598 # they don't declare any unique events, because the concrete class hierarchy | 598 # they don't declare any unique events, because the concrete class hierarchy |
| 599 # doesn't match the interface hierarchy. | 599 # doesn't match the interface hierarchy. |
| 600 _html_explicit_event_classes = set(['DocumentFragment']) | 600 _html_explicit_event_classes = set(['DocumentFragment']) |
| 601 | 601 |
| 602 def _OnAttributeToEventName(on_method): | 602 def _OnAttributeToEventName(on_method): |
| (...skipping 12 matching lines...) Expand all Loading... |
| 615 return sorted(event_names, key=lambda name: _html_event_names[name]) | 615 return sorted(event_names, key=lambda name: _html_event_names[name]) |
| 616 | 616 |
| 617 def DomToHtmlEvent(event_name): | 617 def DomToHtmlEvent(event_name): |
| 618 assert event_name in _html_event_names, \ | 618 assert event_name in _html_event_names, \ |
| 619 'No known html event name for event: ' + event_name | 619 'No known html event name for event: ' + event_name |
| 620 return _html_event_names[event_name] | 620 return _html_event_names[event_name] |
| 621 | 621 |
| 622 # ------------------------------------------------------------------------------ | 622 # ------------------------------------------------------------------------------ |
| 623 class HtmlSystemShared(object): | 623 class HtmlSystemShared(object): |
| 624 | 624 |
| 625 def __init__(self, database): | 625 def __init__(self, context): |
| 626 self._event_classes = set() | 626 self._event_classes = set() |
| 627 self._seen_event_names = {} | 627 self._seen_event_names = {} |
| 628 self._database = database | 628 self._database = context.database |
| 629 self._inheritance_closure = _ComputeInheritanceClosure(database) | 629 self._type_registry = context.type_registry |
| 630 self._html_renames = self._MakeHtmlRenames() | 630 self._inheritance_closure = _ComputeInheritanceClosure(self._database) |
| 631 | 631 |
| 632 def _HasAncestor(self, interface, names_to_match): | 632 @staticmethod |
| 633 def _HasAncestor(database, interface, names_to_match): |
| 633 for parent in interface.parents: | 634 for parent in interface.parents: |
| 634 if parent.type.id in names_to_match: | 635 if parent.type.id in names_to_match: |
| 635 return True | 636 return True |
| 636 if not self._database.HasInterface(parent.type.id): | 637 if not database.HasInterface(parent.type.id): |
| 637 continue | 638 continue |
| 638 parent_interface = self._database.GetInterface(parent.type.id) | 639 parent_interface = database.GetInterface(parent.type.id) |
| 639 if self._HasAncestor(parent_interface, names_to_match): | 640 if HtmlSystemShared._HasAncestor(database, parent_interface, names_to_matc
h): |
| 640 return True | 641 return True |
| 641 return False | 642 return False |
| 642 | 643 |
| 643 def _MakeHtmlRenames(self): | 644 @staticmethod |
| 645 def MakeHtmlRenames(database): |
| 644 html_renames = {} | 646 html_renames = {} |
| 645 | 647 |
| 646 for interface in self._database.GetInterfaces(): | 648 for interface in database.GetInterfaces(): |
| 647 if (interface.id.startswith('HTML') and | 649 if (interface.id.startswith('HTML') and |
| 648 self._HasAncestor(interface, ['Element', 'Document'])): | 650 HtmlSystemShared._HasAncestor(database, interface, ['Element', 'Docume
nt'])): |
| 649 html_renames[interface.id] = interface.id[4:] | 651 html_renames[interface.id] = interface.id[4:] |
| 650 | 652 |
| 651 for subclass in _html_strip_webkit_prefix_classes: | 653 for subclass in _html_strip_webkit_prefix_classes: |
| 652 html_renames['WebKit' + subclass] = subclass | 654 html_renames['WebKit' + subclass] = subclass |
| 653 | 655 |
| 654 # TODO(jacobr): we almost want to add this commented out line back. | 656 # TODO(jacobr): we almost want to add this commented out line back. |
| 655 # html_renames['HTMLCollection'] = 'ElementList' | 657 # html_renames['HTMLCollection'] = 'ElementList' |
| 656 # html_renames['NodeList'] = 'ElementList' | 658 # html_renames['NodeList'] = 'ElementList' |
| 657 # html_renames['HTMLOptionsCollection'] = 'ElementList' | 659 # html_renames['HTMLOptionsCollection'] = 'ElementList' |
| 658 html_renames['DOMWindow'] = 'Window' | 660 html_renames['DOMWindow'] = 'Window' |
| 659 | 661 |
| 660 return html_renames | 662 return html_renames |
| 661 | 663 |
| 662 def _HTMLInterfaceName(self, interface_name): | |
| 663 return self._html_renames.get(interface_name, interface_name) | |
| 664 | |
| 665 def _FindMatch(self, interface_name, member, member_prefix, candidates): | 664 def _FindMatch(self, interface_name, member, member_prefix, candidates): |
| 666 for ancestor_name in self._AllAncestorInterfaces(interface_name): | 665 for ancestor_name in self._AllAncestorInterfaces(interface_name): |
| 667 name = self._HTMLInterfaceName(ancestor_name) + '.' + member | 666 name = self._DartType(ancestor_name) + '.' + member |
| 668 if name in candidates: | 667 if name in candidates: |
| 669 return name | 668 return name |
| 670 name = (self._HTMLInterfaceName(interface_name) + '.' + member_prefix + | 669 name = (self._DartType(interface_name) + '.' + member_prefix + |
| 671 member) | 670 member) |
| 672 if name in candidates: | 671 if name in candidates: |
| 673 return name | 672 return name |
| 674 return None | 673 return None |
| 675 | 674 |
| 676 def _AllAncestorInterfaces(self, interface_name): | 675 def _AllAncestorInterfaces(self, interface_name): |
| 677 return [interface_name] + self._inheritance_closure[interface_name] | 676 return [interface_name] + self._inheritance_closure[interface_name] |
| 678 | 677 |
| 679 def RenameInHtmlLibrary(self, interface_name, member, member_prefix='', | 678 def RenameInHtmlLibrary(self, interface_name, member, member_prefix='', |
| 680 implementation_class=False): | 679 implementation_class=False): |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 for interface in interfaces_with_events: | 730 for interface in interfaces_with_events: |
| 732 names.append(interface.id + 'Events') | 731 names.append(interface.id + 'Events') |
| 733 return names | 732 return names |
| 734 | 733 |
| 735 def GetParentEventsClass(self, interface): | 734 def GetParentEventsClass(self, interface): |
| 736 parent_event_classes = self.GetParentsEventsClasses(interface) | 735 parent_event_classes = self.GetParentsEventsClasses(interface) |
| 737 if len(parent_event_classes) != 1: | 736 if len(parent_event_classes) != 1: |
| 738 raise Exception('Only one parent event class allowed ' + interface.id) | 737 raise Exception('Only one parent event class allowed ' + interface.id) |
| 739 return parent_event_classes[0] | 738 return parent_event_classes[0] |
| 740 | 739 |
| 741 def _ImplClassName(self, type_name): | |
| 742 return '_' + type_name + 'Impl' | |
| 743 | |
| 744 # This returns two values: the first is whether or not an "on" property should | 740 # This returns two values: the first is whether or not an "on" property should |
| 745 # be generated for the interface, and the second is the event attributes to | 741 # be generated for the interface, and the second is the event attributes to |
| 746 # generate if it should. | 742 # generate if it should. |
| 747 def GetEventAttributes(self, interface): | 743 def GetEventAttributes(self, interface): |
| 748 events = set([attr for attr in interface.attributes | 744 events = set([attr for attr in interface.attributes |
| 749 if attr.type.id == 'EventListener']) | 745 if attr.type.id == 'EventListener']) |
| 750 | 746 |
| 751 if events or interface.id in _html_explicit_event_classes: | 747 if events or interface.id in _html_explicit_event_classes: |
| 752 return True, events | 748 return True, events |
| 753 else: | 749 else: |
| 754 return False, None | 750 return False, None |
| 755 | 751 |
| 756 def IsPrivate(self, name): | 752 def IsPrivate(self, name): |
| 757 return name.startswith('_') | 753 return name.startswith('_') |
| 758 | 754 |
| 759 def DartType(self, idl_type): | 755 def _DartType(self, type_name): |
| 760 type_info = TypeRegistry().TypeInfo(idl_type) | 756 return self._type_registry.DartType(type_name) |
| 761 return self._HTMLInterfaceName(type_info.dart_type()) | |
| 762 | 757 |
| 763 class HtmlSystem(System): | |
| 764 | 758 |
| 765 def __init__(self, context): | 759 class HtmlInterfacesSystem(System): |
| 766 super(HtmlSystem, self).__init__(context) | |
| 767 self._shared = HtmlSystemShared(self._database) | |
| 768 | |
| 769 class HtmlInterfacesSystem(HtmlSystem): | |
| 770 | 760 |
| 771 def __init__(self, context, backend): | 761 def __init__(self, context, backend): |
| 772 super(HtmlInterfacesSystem, self).__init__(context) | 762 super(HtmlInterfacesSystem, self).__init__(context) |
| 773 self._backend = backend | 763 self._backend = backend |
| 764 self._shared = HtmlSystemShared(context) |
| 774 self._dart_interface_file_paths = [] | 765 self._dart_interface_file_paths = [] |
| 775 self._elements_factory_emitter = None | 766 self._elements_factory_emitter = None |
| 776 | 767 |
| 777 def ProcessInterface(self, interface): | 768 def ProcessInterface(self, interface): |
| 778 HtmlDartInterfaceGenerator(self, interface).Generate() | 769 HtmlDartInterfaceGenerator(self, interface).Generate() |
| 779 | 770 |
| 780 def ProcessCallback(self, interface, info): | 771 def ProcessCallback(self, interface, info): |
| 781 """Generates a typedef for the callback interface.""" | 772 """Generates a typedef for the callback interface.""" |
| 782 interface_name = interface.id | 773 interface_name = interface.id |
| 783 file_path = self._FilePathForDartInterface(interface_name) | 774 file_path = self._FilePathForDartInterface(interface_name) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 796 # ------------------------------------------------------------------------------ | 787 # ------------------------------------------------------------------------------ |
| 797 | 788 |
| 798 class HtmlDartInterfaceGenerator(BaseGenerator): | 789 class HtmlDartInterfaceGenerator(BaseGenerator): |
| 799 """Generates dart interface and implementation for the DOM IDL interface.""" | 790 """Generates dart interface and implementation for the DOM IDL interface.""" |
| 800 | 791 |
| 801 def __init__(self, system, interface): | 792 def __init__(self, system, interface): |
| 802 super(HtmlDartInterfaceGenerator, self).__init__( | 793 super(HtmlDartInterfaceGenerator, self).__init__( |
| 803 system._database, interface) | 794 system._database, interface) |
| 804 self._system = system | 795 self._system = system |
| 805 self._shared = system._shared | 796 self._shared = system._shared |
| 806 self._html_interface_name = self._shared._HTMLInterfaceName( | 797 self._html_interface_name = system._type_registry.InterfaceName(self._interf
ace.id) |
| 807 self._interface.id) | |
| 808 self._backend = system._backend.ImplementationGenerator(self._interface) | 798 self._backend = system._backend.ImplementationGenerator(self._interface) |
| 809 | 799 |
| 810 def StartInterface(self): | 800 def StartInterface(self): |
| 811 if not self._interface.id in _merged_html_interfaces: | 801 if not self._interface.id in _merged_html_interfaces: |
| 812 path = self._system._FilePathForDartInterface(self._html_interface_name) | 802 path = self._system._FilePathForDartInterface(self._html_interface_name) |
| 813 self._system._dart_interface_file_paths.append(path) | 803 self._system._dart_interface_file_paths.append(path) |
| 814 self._interface_emitter = self._system._emitters.FileEmitter(path) | 804 self._interface_emitter = self._system._emitters.FileEmitter(path) |
| 815 else: | 805 else: |
| 816 self._interface_emitter = emitter.Emitter() | 806 self._interface_emitter = emitter.Emitter() |
| 817 | 807 |
| 818 template_file = 'interface_%s.darttemplate' % self._html_interface_name | 808 template_file = 'interface_%s.darttemplate' % self._html_interface_name |
| 819 interface_template = (self._system._templates.TryLoad(template_file) or | 809 interface_template = (self._system._templates.TryLoad(template_file) or |
| 820 self._system._templates.Load('interface.darttemplate')
) | 810 self._system._templates.Load('interface.darttemplate')
) |
| 821 | 811 |
| 822 typename = self._html_interface_name | 812 typename = self._html_interface_name |
| 823 | 813 |
| 824 extends = [] | 814 extends = [] |
| 825 suppressed_extends = [] | 815 suppressed_extends = [] |
| 826 | 816 |
| 827 for parent in self._interface.parents: | 817 for parent in self._interface.parents: |
| 828 # TODO(vsm): Remove source_filter. | 818 # TODO(vsm): Remove source_filter. |
| 829 if MatchSourceFilter(parent): | 819 if MatchSourceFilter(parent): |
| 830 # Parent is a DOM type. | 820 # Parent is a DOM type. |
| 831 extends.append(self._shared.DartType(parent.type.id)) | 821 extends.append(self._DartType(parent.type.id)) |
| 832 elif '<' in parent.type.id: | 822 elif '<' in parent.type.id: |
| 833 # Parent is a Dart collection type. | 823 # Parent is a Dart collection type. |
| 834 # TODO(vsm): Make this check more robust. | 824 # TODO(vsm): Make this check more robust. |
| 835 extends.append(self._shared.DartType(parent.type.id)) | 825 extends.append(self._DartType(parent.type.id)) |
| 836 else: | 826 else: |
| 837 suppressed_extends.append('%s.%s' % | 827 suppressed_extends.append('%s.%s' % |
| 838 (self._common_prefix, self._shared.DartType(parent.type.id))) | 828 (self._common_prefix, self._DartType(parent.type.id))) |
| 839 | 829 |
| 840 comment = ' extends' | 830 comment = ' extends' |
| 841 extends_str = '' | 831 extends_str = '' |
| 842 if extends: | 832 if extends: |
| 843 extends_str += ' extends ' + ', '.join(extends) | 833 extends_str += ' extends ' + ', '.join(extends) |
| 844 comment = ',' | 834 comment = ',' |
| 845 if suppressed_extends: | 835 if suppressed_extends: |
| 846 extends_str += ' /*%s %s */' % (comment, ', '.join(suppressed_extends)) | 836 extends_str += ' /*%s %s */' % (comment, ', '.join(suppressed_extends)) |
| 847 | 837 |
| 848 factory_provider = None | 838 factory_provider = None |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 902 self._implementation_emitter = self._system._emitters.FileEmitter(path) | 892 self._implementation_emitter = self._system._emitters.FileEmitter(path) |
| 903 else: | 893 else: |
| 904 self._implementation_emitter = emitter.Emitter() | 894 self._implementation_emitter = emitter.Emitter() |
| 905 self._backend.SetImplementationEmitter(self._implementation_emitter) | 895 self._backend.SetImplementationEmitter(self._implementation_emitter) |
| 906 self._implementation_members_emitter = self._backend.StartInterface() | 896 self._implementation_members_emitter = self._backend.StartInterface() |
| 907 | 897 |
| 908 for constructor_info in constructors: | 898 for constructor_info in constructors: |
| 909 self._members_emitter.Emit( | 899 self._members_emitter.Emit( |
| 910 '\n' | 900 '\n' |
| 911 ' $CTOR($PARAMS);\n', | 901 ' $CTOR($PARAMS);\n', |
| 912 CTOR=self._shared.DartType(constructor_info.ConstructorFullName()), | 902 CTOR=self._DartType(constructor_info.ConstructorFullName()), |
| 913 PARAMS=constructor_info.ParametersInterfaceDeclaration( | 903 PARAMS=constructor_info.ParametersInterfaceDeclaration(self._DartType)
) |
| 914 self._shared.DartType)) | |
| 915 | 904 |
| 916 element_type = MaybeTypedArrayElementTypeInHierarchy( | 905 element_type = MaybeTypedArrayElementTypeInHierarchy( |
| 917 self._interface, self._system._database) | 906 self._interface, self._system._database) |
| 918 if element_type: | 907 if element_type: |
| 919 self._members_emitter.Emit( | 908 self._members_emitter.Emit( |
| 920 '\n' | 909 '\n' |
| 921 ' $CTOR(int length);\n' | 910 ' $CTOR(int length);\n' |
| 922 '\n' | 911 '\n' |
| 923 ' $CTOR.fromList(List<$TYPE> list);\n' | 912 ' $CTOR.fromList(List<$TYPE> list);\n' |
| 924 '\n' | 913 '\n' |
| 925 ' $CTOR.fromBuffer(ArrayBuffer buffer,' | 914 ' $CTOR.fromBuffer(ArrayBuffer buffer,' |
| 926 ' [int byteOffset, int length]);\n', | 915 ' [int byteOffset, int length]);\n', |
| 927 CTOR=self._interface.id, | 916 CTOR=self._interface.id, |
| 928 TYPE=self._shared.DartType(element_type)) | 917 TYPE=self._DartType(element_type)) |
| 929 | 918 |
| 930 self._GenerateEvents() | 919 self._GenerateEvents() |
| 931 | 920 |
| 932 old_backend = self._backend | 921 old_backend = self._backend |
| 933 if not self._backend.ImplementsMergedMembers(): | 922 if not self._backend.ImplementsMergedMembers(): |
| 934 self._backend = HtmlGeneratorDummyBackend() | 923 self._backend = HtmlGeneratorDummyBackend() |
| 935 for merged_interface in _merged_html_interfaces: | 924 for merged_interface in _merged_html_interfaces: |
| 936 if _merged_html_interfaces[merged_interface] == self._interface.id: | 925 if _merged_html_interfaces[merged_interface] == self._interface.id: |
| 937 merged_interface = self._database.GetInterface(merged_interface) | 926 merged_interface = self._database.GetInterface(merged_interface) |
| 938 self.AddMembers(merged_interface) | 927 self.AddMembers(merged_interface) |
| (...skipping 21 matching lines...) Expand all Loading... |
| 960 assert(not html_setter_name or html_name == html_setter_name) | 949 assert(not html_setter_name or html_name == html_setter_name) |
| 961 | 950 |
| 962 if not is_secondary: | 951 if not is_secondary: |
| 963 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */', | 952 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */', |
| 964 DOMINTERFACE=attribute.doc_js_interface_name, | 953 DOMINTERFACE=attribute.doc_js_interface_name, |
| 965 DOMNAME=dom_name) | 954 DOMNAME=dom_name) |
| 966 modifier = 'final ' if read_only else '' | 955 modifier = 'final ' if read_only else '' |
| 967 self._members_emitter.Emit('\n $MODIFIER$TYPE $NAME;\n', | 956 self._members_emitter.Emit('\n $MODIFIER$TYPE $NAME;\n', |
| 968 MODIFIER=modifier, | 957 MODIFIER=modifier, |
| 969 NAME=html_name, | 958 NAME=html_name, |
| 970 TYPE=self._shared.DartType(attribute.type.id)) | 959 TYPE=self._DartType(attribute.type.id)) |
| 971 self._backend.AddAttribute(attribute, html_name, read_only) | 960 self._backend.AddAttribute(attribute, html_name, read_only) |
| 972 | 961 |
| 973 def AddSecondaryAttribute(self, interface, attribute): | 962 def AddSecondaryAttribute(self, interface, attribute): |
| 974 self._backend.SecondaryContext(interface) | 963 self._backend.SecondaryContext(interface) |
| 975 self.AddAttribute(attribute, True) | 964 self.AddAttribute(attribute, True) |
| 976 | 965 |
| 977 def AddOperation(self, info, is_secondary=False): | 966 def AddOperation(self, info, skip_declaration=False): |
| 978 """ | 967 """ |
| 979 Arguments: | 968 Arguments: |
| 980 operations - contains the overloads, one or more operations with the same | 969 operations - contains the overloads, one or more operations with the same |
| 981 name. | 970 name. |
| 982 """ | 971 """ |
| 983 html_name = self._shared.RenameInHtmlLibrary( | 972 html_name = self._shared.RenameInHtmlLibrary(self._interface.id, info.name) |
| 984 self._interface.id, info.name) | 973 if not html_name: |
| 985 if html_name and not self._shared.IsPrivate(html_name) and not is_secondary: | 974 if info.name == 'item': |
| 975 # FIXME: item should be renamed to operator[], not removed. |
| 976 self._backend.AddOperation(info, '_item') |
| 977 return |
| 978 |
| 979 if not self._shared.IsPrivate(html_name) and not skip_declaration: |
| 986 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */', | 980 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */', |
| 987 DOMINTERFACE=info.overloads[0].doc_js_interface_name, | 981 DOMINTERFACE=info.overloads[0].doc_js_interface_name, |
| 988 DOMNAME=info.name) | 982 DOMNAME=info.name) |
| 989 | 983 |
| 990 self._members_emitter.Emit('\n' | 984 self._members_emitter.Emit('\n' |
| 991 ' $TYPE $NAME($PARAMS);\n', | 985 ' $TYPE $NAME($PARAMS);\n', |
| 992 TYPE=self._shared.DartType(info.type_name), | 986 TYPE=self._DartType(info.type_name), |
| 993 NAME=html_name, | 987 NAME=html_name, |
| 994 PARAMS=info.ParametersInterfaceDeclaration( | 988 PARAMS=info.ParametersInterfaceDeclaration(self
._DartType)) |
| 995 self._shared.DartType)) | 989 self._backend.AddOperation(info, html_name) |
| 996 self._backend.AddOperation(info) | |
| 997 | 990 |
| 998 def AddStaticOperation(self, info): | 991 def AddStaticOperation(self, info): |
| 999 self._backend.AddStaticOperation(info) | 992 self.AddOperation(info, True) |
| 1000 | 993 |
| 1001 def AddSecondaryOperation(self, interface, info): | 994 def AddSecondaryOperation(self, interface, info): |
| 1002 self._backend.SecondaryContext(interface) | 995 self._backend.SecondaryContext(interface) |
| 1003 self.AddOperation(info, True) | 996 self.AddOperation(info, True) |
| 1004 | 997 |
| 1005 def FinishInterface(self): | 998 def FinishInterface(self): |
| 1006 self._backend.FinishInterface() | 999 self._backend.FinishInterface() |
| 1007 | 1000 |
| 1008 def AddConstant(self, constant): | 1001 def AddConstant(self, constant): |
| 1009 type = TypeOrNothing(DartType(constant.type.id), constant.type.id) | 1002 type = TypeOrNothing(self._DartType(constant.type.id), constant.type.id) |
| 1010 self._members_emitter.Emit('\n static final $TYPE$NAME = $VALUE;\n', | 1003 self._members_emitter.Emit('\n static final $TYPE$NAME = $VALUE;\n', |
| 1011 NAME=constant.id, | 1004 NAME=constant.id, |
| 1012 TYPE=type, | 1005 TYPE=type, |
| 1013 VALUE=constant.value) | 1006 VALUE=constant.value) |
| 1014 self._backend.AddConstant(constant) | 1007 self._backend.AddConstant(constant) |
| 1015 | 1008 |
| 1016 def _GenerateEvents(self): | 1009 def _GenerateEvents(self): |
| 1017 emit_events, event_attrs = self._shared.GetEventAttributes(self._interface) | 1010 emit_events, event_attrs = self._shared.GetEventAttributes(self._interface) |
| 1018 if not emit_events: | 1011 if not emit_events: |
| 1019 return | 1012 return |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1070 | 1063 |
| 1071 self._implementation_members_emitter.Emit( | 1064 self._implementation_members_emitter.Emit( |
| 1072 '\n $TYPE get on() =>\n new $TYPE(this);\n', | 1065 '\n $TYPE get on() =>\n new $TYPE(this);\n', |
| 1073 TYPE=events_class) | 1066 TYPE=events_class) |
| 1074 | 1067 |
| 1075 | 1068 |
| 1076 class HtmlGeneratorDummyBackend(object): | 1069 class HtmlGeneratorDummyBackend(object): |
| 1077 def AddAttribute(self, attribute, html_name, read_only): | 1070 def AddAttribute(self, attribute, html_name, read_only): |
| 1078 pass | 1071 pass |
| 1079 | 1072 |
| 1080 def AddOperation(self, info): | 1073 def AddOperation(self, info, html_name): |
| 1081 pass | 1074 pass |
| 1082 | 1075 |
| 1083 | 1076 |
| 1084 # ------------------------------------------------------------------------------ | 1077 # ------------------------------------------------------------------------------ |
| 1085 | 1078 |
| 1086 # TODO(jmesserly): inheritance is probably not the right way to factor this long | 1079 # TODO(jmesserly): inheritance is probably not the right way to factor this long |
| 1087 # term, but it makes merging better for now. | 1080 # term, but it makes merging better for now. |
| 1088 class HtmlFrogClassGenerator(FrogInterfaceGenerator): | 1081 class HtmlFrogClassGenerator(FrogInterfaceGenerator): |
| 1089 """Generates a Frog class for the dart:html library from a DOM IDL | 1082 """Generates a Frog class for the dart:html library from a DOM IDL |
| 1090 interface. | 1083 interface. |
| 1091 """ | 1084 """ |
| 1092 | 1085 |
| 1093 def __init__(self, system, interface): | 1086 def __init__(self, system, interface): |
| 1094 super(HtmlFrogClassGenerator, self).__init__( | 1087 super(HtmlFrogClassGenerator, self).__init__( |
| 1095 system, interface, None, None) | 1088 system, interface, None, None) |
| 1096 self._shared = self._system._shared | 1089 self._html_interface_name = system._type_registry.InterfaceName(self._interf
ace.id) |
| 1097 self._html_interface_name = self._shared._HTMLInterfaceName( | |
| 1098 self._interface.id) | |
| 1099 | 1090 |
| 1100 def HasImplementation(self): | 1091 def HasImplementation(self): |
| 1101 return not (IsPureInterface(self._interface.id) or | 1092 return not (IsPureInterface(self._interface.id) or |
| 1102 self._interface.id in _merged_html_interfaces) | 1093 self._interface.id in _merged_html_interfaces) |
| 1103 | 1094 |
| 1104 def ImplementationClassName(self): | 1095 def ImplementationClassName(self): |
| 1105 return self._ImplClassName(self._html_interface_name) | 1096 return self._ImplClassName(self._html_interface_name) |
| 1106 | 1097 |
| 1107 def FilePathForDartImplementation(self): | 1098 def FilePathForDartImplementation(self): |
| 1108 return os.path.join(self._system._output_dir, 'html', 'frog', | 1099 return os.path.join(self._system._output_dir, 'html', 'frog', |
| 1109 '%s.dart' % self._html_interface_name) | 1100 '%s.dart' % self._html_interface_name) |
| 1110 | 1101 |
| 1111 def FilePathForDartFactoryProviderImplementation(self): | 1102 def FilePathForDartFactoryProviderImplementation(self): |
| 1112 return os.path.join(self._system._output_dir, 'html', 'frog', | 1103 return os.path.join(self._system._output_dir, 'html', 'frog', |
| 1113 '_%sFactoryProvider.dart' % self._html_interface_name) | 1104 '_%sFactoryProvider.dart' % self._html_interface_name) |
| 1114 | 1105 |
| 1115 def FilePathForDartElementsFactoryProviderImplementation(self): | 1106 def FilePathForDartElementsFactoryProviderImplementation(self): |
| 1116 return os.path.join(self._system._output_dir, 'html', 'frog', | 1107 return os.path.join(self._system._output_dir, 'html', 'frog', |
| 1117 '_Elements.dart') | 1108 '_Elements.dart') |
| 1118 | 1109 |
| 1119 def SetImplementationEmitter(self, implementation_emitter): | 1110 def SetImplementationEmitter(self, implementation_emitter): |
| 1120 self._dart_code = implementation_emitter | 1111 self._dart_code = implementation_emitter |
| 1121 | 1112 |
| 1122 def ImplementsMergedMembers(self): | 1113 def ImplementsMergedMembers(self): |
| 1123 return True | 1114 return True |
| 1124 | 1115 |
| 1125 def _ImplClassName(self, type_name): | 1116 def _ImplClassName(self, type_name): |
| 1126 return self._shared._ImplClassName(type_name) | 1117 return '_%sImpl' % type_name |
| 1127 | |
| 1128 def _NarrowToImplementationType(self, type_name): | |
| 1129 if self._ShouldNarrowToImplementationType(type_name): | |
| 1130 return self._ImplClassName(self._shared.DartType(type_name)) | |
| 1131 return self._shared.DartType(type_name) | |
| 1132 | 1118 |
| 1133 def StartInterface(self): | 1119 def StartInterface(self): |
| 1134 interface = self._interface | 1120 interface = self._interface |
| 1135 interface_name = interface.id | 1121 interface_name = interface.id |
| 1136 | 1122 |
| 1137 self._class_name = self._ImplClassName(self._html_interface_name) | 1123 self._class_name = self._ImplClassName(self._html_interface_name) |
| 1138 | 1124 |
| 1139 base = None | 1125 base = None |
| 1140 if interface.parents: | 1126 if interface.parents: |
| 1141 supertype = interface.parents[0].type.id | 1127 supertype = interface.parents[0].type.id |
| 1142 if IsDartCollectionType(supertype): | 1128 if IsDartCollectionType(supertype): |
| 1143 # List methods are injected in AddIndexer. | 1129 # List methods are injected in AddIndexer. |
| 1144 pass | 1130 pass |
| 1145 elif IsPureInterface(supertype): | 1131 elif IsPureInterface(supertype): |
| 1146 pass | 1132 pass |
| 1147 else: | 1133 else: |
| 1148 base = self._ImplClassName(self._shared._HTMLInterfaceName(supertype)) | 1134 base = self._ImplClassName(self._DartType(supertype)) |
| 1149 | 1135 |
| 1150 native_spec = MakeNativeSpec(interface.javascript_binding_name) | 1136 native_spec = MakeNativeSpec(interface.javascript_binding_name) |
| 1151 | 1137 |
| 1152 extends = ' extends ' + base if base else '' | 1138 extends = ' extends ' + base if base else '' |
| 1153 | 1139 |
| 1154 # TODO: Include all implemented interfaces, including other Lists. | 1140 # TODO: Include all implemented interfaces, including other Lists. |
| 1155 implements = [self._html_interface_name] | 1141 implements = [self._html_interface_name] |
| 1156 element_type = MaybeTypedArrayElementType(self._interface) | 1142 element_type = MaybeTypedArrayElementType(self._interface) |
| 1157 if element_type: | 1143 if element_type: |
| 1158 implements.append('List<%s>' % self._shared.DartType(element_type)) | 1144 implements.append('List<%s>' % self._DartType(element_type)) |
| 1159 implements.append('JavaScriptIndexingBehavior') | 1145 implements.append('JavaScriptIndexingBehavior') |
| 1160 | 1146 |
| 1161 template_file = 'impl_%s.darttemplate' % self._html_interface_name | 1147 template_file = 'impl_%s.darttemplate' % self._html_interface_name |
| 1162 template = (self._system._templates.TryLoad(template_file) or | 1148 template = (self._system._templates.TryLoad(template_file) or |
| 1163 self._system._templates.Load('frog_impl.darttemplate')) | 1149 self._system._templates.Load('frog_impl.darttemplate')) |
| 1164 self._members_emitter = self._dart_code.Emit( | 1150 self._members_emitter = self._dart_code.Emit( |
| 1165 template, | 1151 template, |
| 1166 #class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC { | 1152 #class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC { |
| 1167 #$!MEMBERS | 1153 #$!MEMBERS |
| 1168 #} | 1154 #} |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1180 template_file = ('factoryprovider_%s.darttemplate' % | 1166 template_file = ('factoryprovider_%s.darttemplate' % |
| 1181 self._html_interface_name) | 1167 self._html_interface_name) |
| 1182 template = self._system._templates.TryLoad(template_file) | 1168 template = self._system._templates.TryLoad(template_file) |
| 1183 if not template: | 1169 if not template: |
| 1184 template = self._system._templates.Load('factoryprovider.darttemplate') | 1170 template = self._system._templates.Load('factoryprovider.darttemplate') |
| 1185 | 1171 |
| 1186 emitter.Emit( | 1172 emitter.Emit( |
| 1187 template, | 1173 template, |
| 1188 FACTORYPROVIDER=factory_provider, | 1174 FACTORYPROVIDER=factory_provider, |
| 1189 CONSTRUCTOR=self._html_interface_name, | 1175 CONSTRUCTOR=self._html_interface_name, |
| 1190 PARAMETERS=constructor_info.ParametersImplementationDeclaration(), | 1176 PARAMETERS=constructor_info.ParametersImplementationDeclaration(self._Da
rtType), |
| 1191 NAMED_CONSTRUCTOR=constructor_info.name or self._html_interface_name, | 1177 NAMED_CONSTRUCTOR=constructor_info.name or self._html_interface_name, |
| 1192 ARGUMENTS=constructor_info.ParametersAsArgumentList()) | 1178 ARGUMENTS=constructor_info.ParametersAsArgumentList()) |
| 1193 | 1179 |
| 1194 def AddIndexer(self, element_type): | 1180 def AddIndexer(self, element_type): |
| 1195 """Adds all the methods required to complete implementation of List.""" | 1181 """Adds all the methods required to complete implementation of List.""" |
| 1196 # We would like to simply inherit the implementation of everything except | 1182 # We would like to simply inherit the implementation of everything except |
| 1197 # get length(), [], and maybe []=. It is possible to extend from a base | 1183 # get length(), [], and maybe []=. It is possible to extend from a base |
| 1198 # array implementation class only when there is no other implementation | 1184 # array implementation class only when there is no other implementation |
| 1199 # inheritance. There might be no implementation inheritance other than | 1185 # inheritance. There might be no implementation inheritance other than |
| 1200 # DOMBaseWrapper for many classes, but there might be some where the | 1186 # DOMBaseWrapper for many classes, but there might be some where the |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1230 ' void operator[]=(int index, $TYPE value) {\n' | 1216 ' void operator[]=(int index, $TYPE value) {\n' |
| 1231 ' throw new UnsupportedOperationException("Cannot assign element
of immutable List.");\n' | 1217 ' throw new UnsupportedOperationException("Cannot assign element
of immutable List.");\n' |
| 1232 ' }\n', | 1218 ' }\n', |
| 1233 TYPE=self._NarrowInputType(element_type)) | 1219 TYPE=self._NarrowInputType(element_type)) |
| 1234 | 1220 |
| 1235 # TODO(sra): Use separate mixins for mutable implementations of List<T>. | 1221 # TODO(sra): Use separate mixins for mutable implementations of List<T>. |
| 1236 # TODO(sra): Use separate mixins for typed array implementations of List<T>. | 1222 # TODO(sra): Use separate mixins for typed array implementations of List<T>. |
| 1237 if self._interface.id != 'NodeList': | 1223 if self._interface.id != 'NodeList': |
| 1238 template_file = 'immutable_list_mixin.darttemplate' | 1224 template_file = 'immutable_list_mixin.darttemplate' |
| 1239 template = self._system._templates.Load(template_file) | 1225 template = self._system._templates.Load(template_file) |
| 1240 self._members_emitter.Emit(template, E=self._shared.DartType(element_type)
) | 1226 self._members_emitter.Emit(template, E=self._DartType(element_type)) |
| 1241 | 1227 |
| 1242 def AddAttribute(self, attribute, html_name, read_only): | 1228 def AddAttribute(self, attribute, html_name, read_only): |
| 1243 if self._HasCustomImplementation(attribute.id): | 1229 if self._HasCustomImplementation(attribute.id): |
| 1244 return | 1230 return |
| 1245 | 1231 |
| 1246 if attribute.id != html_name: | 1232 if attribute.id != html_name: |
| 1247 self._AddRenamingGetter(attribute, html_name) | 1233 self._AddRenamingGetter(attribute, html_name) |
| 1248 if not read_only: | 1234 if not read_only: |
| 1249 self._AddRenamingSetter(attribute, html_name) | 1235 self._AddRenamingSetter(attribute, html_name) |
| 1250 return | 1236 return |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1303 TYPE=return_type) | 1289 TYPE=return_type) |
| 1304 | 1290 |
| 1305 def _AddRenamingSetter(self, attr, html_name): | 1291 def _AddRenamingSetter(self, attr, html_name): |
| 1306 self._members_emitter.Emit( | 1292 self._members_emitter.Emit( |
| 1307 '\n void set $HTML_NAME($TYPE value)' | 1293 '\n void set $HTML_NAME($TYPE value)' |
| 1308 ' native "this.$NAME = value;";\n', | 1294 ' native "this.$NAME = value;";\n', |
| 1309 HTML_NAME=html_name, | 1295 HTML_NAME=html_name, |
| 1310 NAME=attr.id, | 1296 NAME=attr.id, |
| 1311 TYPE=self._NarrowInputType(attr.type.id)) | 1297 TYPE=self._NarrowInputType(attr.type.id)) |
| 1312 | 1298 |
| 1313 def AddOperation(self, info): | 1299 def AddOperation(self, info, html_name): |
| 1314 """ | 1300 """ |
| 1315 Arguments: | 1301 Arguments: |
| 1316 info: An OperationInfo object. | 1302 info: An OperationInfo object. |
| 1317 """ | 1303 """ |
| 1318 if self._HasCustomImplementation(info.name): | 1304 if self._HasCustomImplementation(info.name): |
| 1319 return | 1305 return |
| 1320 | 1306 |
| 1321 html_name = self._shared.RenameInHtmlLibrary( | 1307 # FIXME: support static operations. |
| 1322 self._interface.id, info.name, implementation_class=True) | 1308 if info.IsStatic(): |
| 1323 if not html_name: | |
| 1324 return | 1309 return |
| 1325 | 1310 |
| 1326 # Do we need a native body? | 1311 # Do we need a native body? |
| 1327 if html_name != info.declared_name: | 1312 if html_name != info.declared_name: |
| 1328 return_type = self._NarrowOutputType(info.type_name) | 1313 return_type = self._NarrowOutputType(info.type_name) |
| 1329 | 1314 |
| 1330 operation_emitter = self._members_emitter.Emit('$!SCOPE', | 1315 operation_emitter = self._members_emitter.Emit('$!SCOPE', |
| 1331 TYPE=return_type, | 1316 TYPE=return_type, |
| 1332 HTML_NAME=html_name, | 1317 HTML_NAME=html_name, |
| 1333 NAME=info.declared_name, | 1318 NAME=info.declared_name, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1345 NAME=info.name, | 1330 NAME=info.name, |
| 1346 PARAMS=info.ParametersImplementationDeclaration( | 1331 PARAMS=info.ParametersImplementationDeclaration( |
| 1347 lambda type_name: self._NarrowInputType(type_name))) | 1332 lambda type_name: self._NarrowInputType(type_name))) |
| 1348 | 1333 |
| 1349 def _HasCustomImplementation(self, member_name): | 1334 def _HasCustomImplementation(self, member_name): |
| 1350 member_name = '%s.%s' % (self._html_interface_name, member_name) | 1335 member_name = '%s.%s' % (self._html_interface_name, member_name) |
| 1351 return member_name in _js_custom_members | 1336 return member_name in _js_custom_members |
| 1352 | 1337 |
| 1353 # ------------------------------------------------------------------------------ | 1338 # ------------------------------------------------------------------------------ |
| 1354 | 1339 |
| 1355 class HtmlFrogSystem(HtmlSystem): | 1340 class HtmlFrogSystem(System): |
| 1356 | 1341 |
| 1357 def __init__(self, context): | 1342 def __init__(self, context): |
| 1358 super(HtmlFrogSystem, self).__init__(context) | 1343 super(HtmlFrogSystem, self).__init__(context) |
| 1359 | 1344 |
| 1360 def ImplementationGenerator(self, interface): | 1345 def ImplementationGenerator(self, interface): |
| 1361 return HtmlFrogClassGenerator(self, interface) | 1346 return HtmlFrogClassGenerator(self, interface) |
| 1362 | 1347 |
| 1363 def GenerateLibraries(self, dart_files): | 1348 def GenerateLibraries(self, dart_files): |
| 1364 self._GenerateLibFile( | 1349 self._GenerateLibFile( |
| 1365 'html_frog.darttemplate', | 1350 'html_frog.darttemplate', |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1387 Collect(database.GetInterface(parent.type.id), | 1372 Collect(database.GetInterface(parent.type.id), |
| 1388 seen, collected) | 1373 seen, collected) |
| 1389 | 1374 |
| 1390 inheritance_closure = {} | 1375 inheritance_closure = {} |
| 1391 for interface in database.GetInterfaces(): | 1376 for interface in database.GetInterfaces(): |
| 1392 seen = set() | 1377 seen = set() |
| 1393 collected = [] | 1378 collected = [] |
| 1394 Collect(interface, seen, collected) | 1379 Collect(interface, seen, collected) |
| 1395 inheritance_closure[interface.id] = collected | 1380 inheritance_closure[interface.id] = collected |
| 1396 return inheritance_closure | 1381 return inheritance_closure |
| OLD | NEW |