Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: lib/dom/scripts/systemhtml.py

Issue 10378040: Generate and use cross frame wrappers for types in other frames/windows. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Factored out template Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 from systemfrog import * 9 from systemfrog import *
10 from systeminterface import * 10 from systeminterface import *
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 } 105 }
106 # Members and classes from the dom that should be removed completelly from 106 # Members and classes from the dom that should be removed completelly from
107 # dart:html. These could be expressed in the IDL instead but expressing this 107 # dart:html. These could be expressed in the IDL instead but expressing this
108 # as a simple table instead is more concise. 108 # as a simple table instead is more concise.
109 # Syntax is: ClassName.(get\.|set\.)?MemberName 109 # Syntax is: ClassName.(get\.|set\.)?MemberName
110 # Using get: and set: is optional and should only be used when a getter needs 110 # Using get: and set: is optional and should only be used when a getter needs
111 # to be suppressed but not the setter, etc. 111 # to be suppressed but not the setter, etc.
112 # TODO(jacobr): cleanup and augment this list. 112 # TODO(jacobr): cleanup and augment this list.
113 _html_library_remove = set([ 113 _html_library_remove = set([
114 'Window.get:document', # Removed as we have a custom implementation. 114 'Window.get:document', # Removed as we have a custom implementation.
115 'Window.get:window',
115 'NodeList.item', 116 'NodeList.item',
116 "Attr.*", 117 "Attr.*",
117 # "BarProp.*", 118 # "BarProp.*",
118 # "BarInfo.*", 119 # "BarInfo.*",
119 # "Blob.webkitSlice", 120 # "Blob.webkitSlice",
120 # "CDATASection.*", 121 # "CDATASection.*",
121 # "Comment.*", 122 # "Comment.*",
122 # "DOMImplementation.*", 123 # "DOMImplementation.*",
123 "Document.get:forms", 124 "Document.get:forms",
124 # "Document.get:selectedStylesheetSet", 125 # "Document.get:selectedStylesheetSet",
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 'write': 'write', 430 'write': 'write',
430 'writeend': 'writeEnd', 431 'writeend': 'writeEnd',
431 'writestart': 'writeStart' 432 'writestart': 'writeStart'
432 } 433 }
433 434
434 # These classes require an explicit declaration for the "on" method even though 435 # These classes require an explicit declaration for the "on" method even though
435 # they don't declare any unique events, because the concrete class hierarchy 436 # they don't declare any unique events, because the concrete class hierarchy
436 # doesn't match the interface hierarchy. 437 # doesn't match the interface hierarchy.
437 _html_explicit_event_classes = set(['DocumentFragment']) 438 _html_explicit_event_classes = set(['DocumentFragment'])
438 439
440 # These types are accessible from different frames. We provide a
441 # wrapper to restrict cross-frame access. Ideally, we capture this
442 # via the IDL CheckSecurity attribute. Currently, it is sometimes
443 # only defined under #define V8_BINDING.
sra1 2012/05/10 00:12:06 What are the tuple elements?
444 _cross_frame_wrapped_types = {
445 'Window': ('get:window', 'window'),
446 'Location': ('Window.get:location', 'window.location'),
447 'History': ('Window.get:history', 'window.history'),
448 }
449
450 _wrapped_types = _cross_frame_wrapped_types.keys()
sra1 2012/05/10 00:12:06 Comment that this list may be extended to non-cros
451
452 def _WrapAndReturnObject(container_interface, return_interface, expr, getter):
sra1 2012/05/10 00:12:06 Just make this wrap the expression. _WrapIfCrossFr
453 if return_interface in _cross_frame_wrapped_types.keys():
sra1 2012/05/10 00:12:06 You can use 'in' on dictionaries directly.
454 full_name = container_interface + '.get:' + getter
455 if _cross_frame_wrapped_types[return_interface][0] == full_name:
456 return 'return %s' % expr
457 return 'return _%sCrossFrameImpl._createSafe(%s)' % (return_interface, expr)
458 return 'return %s' % expr
459
439 def _OnAttributeToEventName(on_method): 460 def _OnAttributeToEventName(on_method):
440 event_name = on_method.id[2:] 461 event_name = on_method.id[2:]
441 if event_name in _on_attribute_to_event_name_mapping: 462 if event_name in _on_attribute_to_event_name_mapping:
442 return _on_attribute_to_event_name_mapping[event_name] 463 return _on_attribute_to_event_name_mapping[event_name]
443 else: 464 else:
444 return event_name 465 return event_name
445 466
446 def _DomToHtmlEvents(interface_id, events): 467 def _DomToHtmlEvents(interface_id, events):
447 event_names = set(map(_OnAttributeToEventName, events)) 468 event_names = set(map(_OnAttributeToEventName, events))
448 if interface_id in _html_manual_events: 469 if interface_id in _html_manual_events:
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 def GenerateLibraries(self, lib_dir): 635 def GenerateLibraries(self, lib_dir):
615 pass 636 pass
616 637
617 638
618 def _FilePathForDartInterface(self, interface_name): 639 def _FilePathForDartInterface(self, interface_name):
619 """Returns the file path of the Dart interface definition.""" 640 """Returns the file path of the Dart interface definition."""
620 # TODO(jmesserly): is this the right path 641 # TODO(jmesserly): is this the right path
621 return os.path.join(self._output_dir, 'html', 'interface', 642 return os.path.join(self._output_dir, 'html', 'interface',
622 '%s.dart' % interface_name) 643 '%s.dart' % interface_name)
623 644
645 class HtmlCrossFrameSystem(HtmlSystem):
sra1 2012/05/10 00:12:06 I have been ordering them: System1 InterfaceGener
646
647 def __init__(self, templates, database, emitters, output_dir, generator):
648 super(HtmlCrossFrameSystem, self).__init__(
649 templates, database, emitters, output_dir, generator)
650 self._dart_cross_frame_file_paths = []
651
652 def InterfaceGenerator(self,
653 interface,
654 common_prefix,
655 super_interface_name,
656 source_filter):
657 """."""
658 if interface.id not in _cross_frame_wrapped_types.keys():
659 return None
660 template_file = 'crossframe_%s.darttemplate' % interface.id
661 template = self._templates.TryLoad(template_file)
662 if not template:
663 template = self._templates.Load('crossframe_impl.darttemplate')
664
665 dart_code = self._ImplFileEmitter(interface.id)
666 return HtmlCrossFrameGenerator(self, interface, template,
667 super_interface_name, dart_code,
668 self._shared)
669
670 def GenerateLibraries(self, lib_dir):
671 pass
672
673 def Finish(self):
674 pass
675
676 def ProcessCallback(self, interface, info):
677 pass
678
679 def _ImplFileEmitter(self, name):
680 """Returns the file emitter of the Frog implementation file."""
681 # TODO(jmesserly): is this the right path
682 path = os.path.join(self._output_dir, 'html', 'crossframe',
683 '%sCrossFrame.dart' % name)
684 self._dart_cross_frame_file_paths.append(path)
685 return self._emitters.FileEmitter(path)
686
624 # ------------------------------------------------------------------------------ 687 # ------------------------------------------------------------------------------
625 688
626 # TODO(jmesserly): inheritance is probably not the right way to factor this long 689 # TODO(jmesserly): inheritance is probably not the right way to factor this long
627 # term, but it makes merging better for now. 690 # term, but it makes merging better for now.
628 class HtmlDartInterfaceGenerator(DartInterfaceGenerator): 691 class HtmlDartInterfaceGenerator(DartInterfaceGenerator):
629 """Generates Dart Interface definition for one DOM IDL interface.""" 692 """Generates Dart Interface definition for one DOM IDL interface."""
630 693
631 def __init__(self, interface, emitter, template, 694 def __init__(self, interface, emitter, template,
632 common_prefix, super_interface, source_filter, system, shared): 695 common_prefix, super_interface, source_filter, system, shared):
633 super(HtmlDartInterfaceGenerator, self).__init__(interface, 696 super(HtmlDartInterfaceGenerator, self).__init__(interface,
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 769
707 emit_events, events = self._shared.GetEventAttributes(self._interface) 770 emit_events, events = self._shared.GetEventAttributes(self._interface)
708 if not emit_events: 771 if not emit_events:
709 return 772 return
710 elif events: 773 elif events:
711 self.AddEventAttributes(events) 774 self.AddEventAttributes(events)
712 else: 775 else:
713 self._EmitEventGetter(self._shared.GetParentEventsClass(self._interface)) 776 self._EmitEventGetter(self._shared.GetParentEventsClass(self._interface))
714 777
715 def AddAttribute(self, getter, setter): 778 def AddAttribute(self, getter, setter):
779 if 'CheckSecurityForNode' in (getter or setter).ext_attrs:
sra1 2012/05/10 00:12:06 Comment on why.
780 return
781
716 dom_name = DartDomNameOfAttribute(getter) 782 dom_name = DartDomNameOfAttribute(getter)
717 html_getter_name = self._shared.RenameInHtmlLibrary( 783 html_getter_name = self._shared.RenameInHtmlLibrary(
718 self._interface, dom_name, 'get:') 784 self._interface, dom_name, 'get:')
719 html_setter_name = self._shared.RenameInHtmlLibrary( 785 html_setter_name = self._shared.RenameInHtmlLibrary(
720 self._interface, dom_name, 'set:') 786 self._interface, dom_name, 'set:')
721 787
722 if not html_getter_name or self._shared.IsPrivate(html_getter_name): 788 if not html_getter_name or self._shared.IsPrivate(html_getter_name):
723 getter = None 789 getter = None
724 if not html_setter_name or self._shared.IsPrivate(html_setter_name): 790 if not html_setter_name or self._shared.IsPrivate(html_setter_name):
725 setter = None 791 setter = None
(...skipping 29 matching lines...) Expand all
755 """ 821 """
756 html_name = self._shared.RenameInHtmlLibrary( 822 html_name = self._shared.RenameInHtmlLibrary(
757 self._interface, info.name) 823 self._interface, info.name)
758 if html_name and not self._shared.IsPrivate(html_name): 824 if html_name and not self._shared.IsPrivate(html_name):
759 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */', 825 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */',
760 DOMINTERFACE=info.overloads[0].doc_js_interface_name, 826 DOMINTERFACE=info.overloads[0].doc_js_interface_name,
761 DOMNAME=info.name) 827 DOMNAME=info.name)
762 828
763 self._members_emitter.Emit('\n' 829 self._members_emitter.Emit('\n'
764 ' $TYPE $NAME($PARAMS);\n', 830 ' $TYPE $NAME($PARAMS);\n',
765 TYPE=info.type_name, 831 TYPE=info.type_name,
766 NAME=html_name, 832 NAME=html_name,
767 PARAMS=info.ParametersInterfaceDeclaration()) 833 PARAMS=info.ParametersInterfaceDeclaration())
768 834
769 def FinishInterface(self): 835 def FinishInterface(self):
770 pass 836 pass
771 837
772 def AddConstant(self, constant): 838 def AddConstant(self, constant):
773 self._EmitConstant(self._members_emitter, constant) 839 self._EmitConstant(self._members_emitter, constant)
774 840
775 def AddEventAttributes(self, event_attrs): 841 def AddEventAttributes(self, event_attrs):
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 # interface Y extends X, List<T> ... 964 # interface Y extends X, List<T> ...
899 # 965 #
900 # In the non-root case we have to choose between: 966 # In the non-root case we have to choose between:
901 # 967 #
902 # class YImpl extends XImpl { add List<T> methods; } 968 # class YImpl extends XImpl { add List<T> methods; }
903 # 969 #
904 # and 970 # and
905 # 971 #
906 # class YImpl extends ListBase<T> { copies of transitive XImpl methods; } 972 # class YImpl extends ListBase<T> { copies of transitive XImpl methods; }
907 # 973 #
974
975 # TODO(vsm): Wrap return value if necessary.
908 self._members_emitter.Emit( 976 self._members_emitter.Emit(
909 '\n' 977 '\n'
910 ' $TYPE operator[](int index) native "return this[index];";\n', 978 ' $TYPE operator[](int index) native "return this[index];";\n',
911 TYPE=self._NarrowOutputType(element_type)) 979 TYPE=self._NarrowOutputType(element_type))
912 980
913 if 'CustomIndexedSetter' in self._interface.ext_attrs: 981 if 'CustomIndexedSetter' in self._interface.ext_attrs:
914 self._members_emitter.Emit( 982 self._members_emitter.Emit(
915 '\n' 983 '\n'
916 ' void operator[]=(int index, $TYPE value) native "this[index] = valu e";\n', 984 ' void operator[]=(int index, $TYPE value) native "this[index] = valu e";\n',
917 TYPE=self._NarrowInputType(element_type)) 985 TYPE=self._NarrowInputType(element_type))
(...skipping 10 matching lines...) Expand all
928 TYPE=self._NarrowInputType(element_type)) 996 TYPE=self._NarrowInputType(element_type))
929 997
930 # TODO(sra): Use separate mixins for mutable implementations of List<T>. 998 # TODO(sra): Use separate mixins for mutable implementations of List<T>.
931 # TODO(sra): Use separate mixins for typed array implementations of List<T>. 999 # TODO(sra): Use separate mixins for typed array implementations of List<T>.
932 if self._interface.id != 'NodeList': 1000 if self._interface.id != 'NodeList':
933 template_file = 'immutable_list_mixin.darttemplate' 1001 template_file = 'immutable_list_mixin.darttemplate'
934 template = self._system._templates.Load(template_file) 1002 template = self._system._templates.Load(template_file)
935 self._members_emitter.Emit(template, E=DartType(element_type)) 1003 self._members_emitter.Emit(template, E=DartType(element_type))
936 1004
937 def AddAttribute(self, getter, setter): 1005 def AddAttribute(self, getter, setter):
938 1006 if 'CheckSecurityForNode' in (getter or setter).ext_attrs:
1007 return
939 html_getter_name = self._shared.RenameInHtmlLibrary( 1008 html_getter_name = self._shared.RenameInHtmlLibrary(
940 self._interface, DartDomNameOfAttribute(getter), 'get:', 1009 self._interface, DartDomNameOfAttribute(getter), 'get:',
941 implementation_class=True) 1010 implementation_class=True)
942 html_setter_name = self._shared.RenameInHtmlLibrary( 1011 html_setter_name = self._shared.RenameInHtmlLibrary(
943 self._interface, DartDomNameOfAttribute(getter), 'set:', 1012 self._interface, DartDomNameOfAttribute(getter), 'set:',
944 implementation_class=True) 1013 implementation_class=True)
945 1014
946 if not html_getter_name: 1015 if not html_getter_name:
947 getter = None 1016 getter = None
948 if not html_setter_name: 1017 if not html_setter_name:
949 setter = None 1018 setter = None
950 1019
951 if not getter and not setter: 1020 if not getter and not setter:
952 return 1021 return
953 1022
954 if ((getter and html_getter_name != getter.id) or 1023 if ((getter and html_getter_name != getter.id) or
955 (setter and html_setter_name != setter.id)): 1024 (setter and html_setter_name != setter.id)):
956 if getter: 1025 if getter:
957 self._AddRenamingGetter(getter, html_getter_name) 1026 self._AddRenamingGetter(getter, html_getter_name)
958 if setter: 1027 if setter:
959 self._AddRenamingSetter(setter, html_setter_name) 1028 self._AddRenamingSetter(setter, html_setter_name)
960 return 1029 return
961 1030
962 # If the (getter, setter) pair is shadowing, we can't generate a shadowing 1031 # If the (getter, setter) pair is shadowing, we can't generate a shadowing
963 # field (Issue 1633). 1032 # field (Issue 1633).
1033
964 (super_getter, super_getter_interface) = self._FindShadowedAttribute(getter) 1034 (super_getter, super_getter_interface) = self._FindShadowedAttribute(getter)
965 (super_setter, super_setter_interface) = self._FindShadowedAttribute(setter) 1035 (super_setter, super_setter_interface) = self._FindShadowedAttribute(setter)
966 if super_getter or super_setter: 1036 if super_getter or super_setter:
967 if getter and not setter and super_getter and not super_setter: 1037 if getter and not setter and super_getter and not super_setter:
968 if DartType(getter.type.id) == DartType(super_getter.type.id): 1038 if DartType(getter.type.id) == DartType(super_getter.type.id):
969 # Compatible getter, use the superclass property. This works because 1039 # Compatible getter, use the superclass property. This works because
970 # JavaScript will do its own dynamic dispatch. 1040 # JavaScript will do its own dynamic dispatch.
971 output_type = getter and self._NarrowOutputType(getter.type.id) 1041 output_type = getter and self._NarrowOutputType(getter.type.id)
972 self._members_emitter.Emit( 1042 self._members_emitter.Emit(
973 '\n' 1043 '\n'
974 ' // Use implementation from $SUPER.\n' 1044 ' // Use implementation from $SUPER.\n'
975 ' // final $TYPE $NAME;\n', 1045 ' // final $TYPE $NAME;\n',
976 SUPER=super_getter_interface.id, 1046 SUPER=super_getter_interface.id,
977 NAME=DartDomNameOfAttribute(getter), 1047 NAME=DartDomNameOfAttribute(getter),
978 TYPE=output_type) 1048 TYPE=output_type)
979 return 1049 return
980 1050
981 self._members_emitter.Emit('\n // Shadowing definition.') 1051 self._members_emitter.Emit('\n // Shadowing definition.')
982 self._AddAttributeUsingProperties(getter, setter) 1052 self._AddAttributeUsingProperties(getter, setter)
983 return 1053 return
984 1054
985 output_type = getter and self._NarrowOutputType(getter.type.id) 1055 # If the return type is wrapped, we cannot just map to a field.
986 input_type = setter and self._NarrowInputType(setter.type.id) 1056 if not getter or getter.type.id not in _wrapped_types:
987 if getter and setter and input_type == output_type: 1057 output_type = getter and self._NarrowOutputType(getter.type.id)
988 self._members_emitter.Emit( 1058 input_type = setter and self._NarrowInputType(setter.type.id)
989 '\n $TYPE $NAME;\n', 1059 if getter and setter and input_type == output_type:
990 NAME=DartDomNameOfAttribute(getter), 1060 self._members_emitter.Emit(
991 TYPE=output_type) 1061 '\n $TYPE $NAME;\n',
992 return 1062 NAME=DartDomNameOfAttribute(getter),
993 if getter and not setter: 1063 TYPE=output_type)
994 self._members_emitter.Emit( 1064 return
995 '\n final $TYPE $NAME;\n', 1065 if getter and not setter:
996 NAME=DartDomNameOfAttribute(getter), 1066 self._members_emitter.Emit(
997 TYPE=output_type) 1067 '\n final $TYPE $NAME;\n',
998 return 1068 NAME=DartDomNameOfAttribute(getter),
1069 TYPE=output_type)
1070 return
999 self._AddAttributeUsingProperties(getter, setter) 1071 self._AddAttributeUsingProperties(getter, setter)
1000 1072
1001 def _AddAttributeUsingProperties(self, getter, setter): 1073 def _AddAttributeUsingProperties(self, getter, setter):
1002 if getter: 1074 if getter:
1003 self._AddGetter(getter) 1075 self._AddGetter(getter)
1004 if setter: 1076 if setter:
1005 self._AddSetter(setter) 1077 self._AddSetter(setter)
1006 1078
1007 def _AddGetter(self, attr): 1079 def _AddGetter(self, attr):
1008 self._AddRenamingGetter(attr, DartDomNameOfAttribute(attr)) 1080 self._AddRenamingGetter(attr, DartDomNameOfAttribute(attr))
1009 1081
1010 def _AddSetter(self, attr): 1082 def _AddSetter(self, attr):
1011 self._AddRenamingSetter(attr, DartDomNameOfAttribute(attr)) 1083 self._AddRenamingSetter(attr, DartDomNameOfAttribute(attr))
1012 1084
1013 def _AddRenamingGetter(self, attr, html_name): 1085 def _AddRenamingGetter(self, attr, html_name):
1086 if attr.type.id in _wrapped_types:
1087 getter = '_' + html_name
1088 else:
1089 getter = html_name
1014 return_type = self._NarrowOutputType(attr.type.id) 1090 return_type = self._NarrowOutputType(attr.type.id)
1015 self._members_emitter.Emit( 1091 self._members_emitter.Emit(
1016 '\n $TYPE get $(HTML_NAME)() native "return this.$NAME;";\n', 1092 '\n $TYPE get $(HTML_NAME)() native "return this.$NAME;";\n',
1017 HTML_NAME=html_name, 1093 HTML_NAME=getter,
1018 NAME=attr.id, 1094 NAME=attr.id,
1019 TYPE=return_type) 1095 TYPE=return_type)
1096 if attr.type.id in _wrapped_types:
1097 self._members_emitter.Emit(
1098 '\n $TYPE get $(HTML_NAME)() {'
sra1 2012/05/10 00:12:06 Any reason not to use => syntax?
1099 '\n $BODY;'
1100 '\n }',
1101 HTML_NAME=html_name,
1102 BODY=_WrapAndReturnObject(self._interface.id, attr.type.id,
1103 getter, html_name),
1104 TYPE=attr.type.id)
1020 1105
1021 def _AddRenamingSetter(self, attr, html_name): 1106 def _AddRenamingSetter(self, attr, html_name):
1022 self._members_emitter.Emit( 1107 self._members_emitter.Emit(
1023 '\n void set $HTML_NAME($TYPE value)' 1108 '\n void set $HTML_NAME($TYPE value)'
1024 ' native "this.$NAME = value;";\n', 1109 ' native "this.$NAME = value;";\n',
1025 HTML_NAME=html_name, 1110 HTML_NAME=html_name,
1026 NAME=attr.id, 1111 NAME=attr.id,
1027 TYPE=self._NarrowInputType(attr.type.id)) 1112 TYPE=self._NarrowInputType(attr.type.id))
1028 1113
1029 def AddOperation(self, info): 1114 def AddOperation(self, info):
1030 """ 1115 """
1031 Arguments: 1116 Arguments:
1032 info: An OperationInfo object. 1117 info: An OperationInfo object.
1033 """ 1118 """
1034 html_name = self._shared.RenameInHtmlLibrary( 1119 html_name = self._shared.RenameInHtmlLibrary(
1035 self._interface, info.name, implementation_class=True) 1120 self._interface, info.name, implementation_class=True)
1036 if not html_name: 1121 if not html_name:
1037 return 1122 return
1038 1123
1039 # Do we need a native body? 1124 # Do we need a native body?
sra1 2012/05/10 00:12:06 "Do we need a wrapper or a native body?"
1040 if html_name != info.declared_name: 1125 if info.type_name in _wrapped_types:
1041 return_type = self._NarrowOutputType(info.type_name) 1126 return_type = self._NarrowOutputType(info.type_name)
1042 1127
1128 operation_emitter = self._members_emitter.Emit('$!SCOPE',
1129 INTERFACE=info.type_name,
1130 TYPE=return_type,
1131 HTML_NAME=html_name,
1132 NAME=info.declared_name,
1133 PARAMS=info.ParametersImplementationDeclaration(
1134 lambda type_name: self._NarrowInputType(type_name)),
1135 ARGLIST=info.ParametersAsArgumentList())
1136
1137 operation_emitter.Emit(
1138 '\n'
1139 ' $TYPE _$(HTML_NAME)($PARAMS) native "$NAME";\n')
1140 operation_emitter.Emit(
sra1 2012/05/10 00:12:06 Could fold this into the previous one.
1141 '\n'
1142 ' $INTERFACE $(HTML_NAME)($PARAMS) =>'
1143 ' _$(INTERFACE)CrossFrameImpl._createSafe(_$HTML_NAME($ARGLIST));\n')
1144
1145 elif html_name != info.declared_name:
1146 return_type = self._NarrowOutputType(info.type_name)
1147
1043 operation_emitter = self._members_emitter.Emit('$!SCOPE', 1148 operation_emitter = self._members_emitter.Emit('$!SCOPE',
1044 TYPE=return_type, 1149 TYPE=return_type,
1045 HTML_NAME=html_name, 1150 HTML_NAME=html_name,
1046 NAME=info.declared_name, 1151 NAME=info.declared_name,
1047 PARAMS=info.ParametersImplementationDeclaration( 1152 PARAMS=info.ParametersImplementationDeclaration(
1048 lambda type_name: self._NarrowInputType(type_name))) 1153 lambda type_name: self._NarrowInputType(type_name)))
1049 1154
1050 operation_emitter.Emit( 1155 operation_emitter.Emit(
1051 '\n' 1156 '\n'
1052 ' $TYPE $(HTML_NAME)($PARAMS) native "$NAME";\n') 1157 ' $TYPE $(HTML_NAME)($PARAMS) native "$NAME";\n')
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 dart_code = self._ImplFileEmitter(interface.id) 1223 dart_code = self._ImplFileEmitter(interface.id)
1119 return HtmlFrogClassGenerator(self, interface, template, 1224 return HtmlFrogClassGenerator(self, interface, template,
1120 super_interface_name, dart_code, self._shared) 1225 super_interface_name, dart_code, self._shared)
1121 1226
1122 def GenerateLibraries(self, lib_dir): 1227 def GenerateLibraries(self, lib_dir):
1123 self._GenerateLibFile( 1228 self._GenerateLibFile(
1124 'html_frog.darttemplate', 1229 'html_frog.darttemplate',
1125 os.path.join(lib_dir, 'html_frog.dart'), 1230 os.path.join(lib_dir, 'html_frog.dart'),
1126 (self._interface_system._dart_interface_file_paths + 1231 (self._interface_system._dart_interface_file_paths +
1127 self._interface_system._dart_callback_file_paths + 1232 self._interface_system._dart_callback_file_paths +
1233 self._cross_frame_system._dart_cross_frame_file_paths +
1128 self._dart_frog_file_paths)) 1234 self._dart_frog_file_paths))
1129 1235
1130 def Finish(self): 1236 def Finish(self):
1131 pass 1237 pass
1132 1238
1133 def _ImplFileEmitter(self, name): 1239 def _ImplFileEmitter(self, name):
1134 """Returns the file emitter of the Frog implementation file.""" 1240 """Returns the file emitter of the Frog implementation file."""
1135 # TODO(jmesserly): is this the right path 1241 # TODO(jmesserly): is this the right path
1136 path = os.path.join(self._output_dir, 'html', 'frog', '%s.dart' % name) 1242 path = os.path.join(self._output_dir, 'html', 'frog', '%s.dart' % name)
1137 self._dart_frog_file_paths.append(path) 1243 self._dart_frog_file_paths.append(path)
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1182 1288
1183 def GenerateLibraries(self, lib_dir): 1289 def GenerateLibraries(self, lib_dir):
1184 # Library generated for implementation. 1290 # Library generated for implementation.
1185 auxiliary_dir = os.path.relpath(self._auxiliary_dir, self._output_dir) 1291 auxiliary_dir = os.path.relpath(self._auxiliary_dir, self._output_dir)
1186 1292
1187 self._GenerateLibFile( 1293 self._GenerateLibFile(
1188 'html_dartium.darttemplate', 1294 'html_dartium.darttemplate',
1189 os.path.join(lib_dir, 'html_dartium.dart'), 1295 os.path.join(lib_dir, 'html_dartium.dart'),
1190 (self._interface_system._dart_interface_file_paths + 1296 (self._interface_system._dart_interface_file_paths +
1191 self._interface_system._dart_callback_file_paths + 1297 self._interface_system._dart_callback_file_paths +
1298 self._cross_frame_system._dart_cross_frame_file_paths +
1192 self._dart_dartium_file_paths 1299 self._dart_dartium_file_paths
1193 ), 1300 ),
1194 AUXILIARY_DIR=MassagePath(auxiliary_dir), 1301 AUXILIARY_DIR=MassagePath(auxiliary_dir),
1195 WRAPCASES='\n'.join(self._wrap_cases)) 1302 WRAPCASES='\n'.join(self._wrap_cases))
1196 1303
1197 def Finish(self): 1304 def Finish(self):
1198 pass 1305 pass
1199 1306
1200 # ------------------------------------------------------------------------------ 1307 # ------------------------------------------------------------------------------
1201 1308
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1379 # Constants are already defined on the interface. 1486 # Constants are already defined on the interface.
1380 pass 1487 pass
1381 1488
1382 def _MethodName(self, prefix, name): 1489 def _MethodName(self, prefix, name):
1383 method_name = prefix + name 1490 method_name = prefix + name
1384 if name in self._base_members: # Avoid illegal Dart 'static override'. 1491 if name in self._base_members: # Avoid illegal Dart 'static override'.
1385 method_name = method_name + '_' + self._interface.id 1492 method_name = method_name + '_' + self._interface.id
1386 return method_name 1493 return method_name
1387 1494
1388 def AddAttribute(self, getter, setter): 1495 def AddAttribute(self, getter, setter):
1496 if 'CheckSecurityForNode' in (getter or setter).ext_attrs:
1497 return
1389 dom_name = DartDomNameOfAttribute(getter or setter) 1498 dom_name = DartDomNameOfAttribute(getter or setter)
1390 html_getter_name = self._shared.RenameInHtmlLibrary( 1499 html_getter_name = self._shared.RenameInHtmlLibrary(
1391 self._interface, dom_name, 'get:', implementation_class=True) 1500 self._interface, dom_name, 'get:', implementation_class=True)
1392 html_setter_name = self._shared.RenameInHtmlLibrary( 1501 html_setter_name = self._shared.RenameInHtmlLibrary(
1393 self._interface, dom_name, 'set:', implementation_class=True) 1502 self._interface, dom_name, 'set:', implementation_class=True)
1394 1503
1395 if getter and html_getter_name: 1504 if getter and html_getter_name:
1396 self._AddGetter(getter, html_getter_name) 1505 self._AddGetter(getter, html_getter_name)
1397 if setter and html_setter_name: 1506 if setter and html_setter_name:
1398 self._AddSetter(setter, html_setter_name) 1507 self._AddSetter(setter, html_setter_name)
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
1700 # dispatch has removed f(X), leaving only f(Y), but there is no guarantee 1809 # dispatch has removed f(X), leaving only f(Y), but there is no guarantee
1701 # that Y = Z-X, so we need to check for Y. 1810 # that Y = Z-X, so we need to check for Y.
1702 true_code = emitter.Emit( 1811 true_code = emitter.Emit(
1703 '$(INDENT)if ($COND) {\n' 1812 '$(INDENT)if ($COND) {\n'
1704 '$!TRUE' 1813 '$!TRUE'
1705 '$(INDENT)}\n', 1814 '$(INDENT)}\n',
1706 COND=test, INDENT=indent) 1815 COND=test, INDENT=indent)
1707 self.GenerateDispatch( 1816 self.GenerateDispatch(
1708 true_code, info, indent + ' ', position + 1, positive) 1817 true_code, info, indent + ' ', position + 1, positive)
1709 return True 1818 return True
1819
1820 # ------------------------------------------------------------------------------
1821
1822 # TODO(jacobr): there is far too much duplicated code between these bindings
1823 # and the Frog bindings. A larger scale refactoring needs to be performed to
1824 # reduce the duplicated logic.
1825 class HtmlCrossFrameGenerator(object):
1826 """Generates a cross-frame implementation of interfaces that must be
1827 securely exposed to other frames/isolates. The cross-frame
1828 implementation wraps the underlying implemation, only providing APIs
1829 deemded secure."""
1830
1831 def __init__(self, system, interface, template, super_interface, dart_code,
1832 shared):
1833 """Generates Dart cross-frame wrapper code for the given interface.
1834
1835 Args:
1836 system: system that is executing this generator.
1837 template: template that output is generated into.
1838 interface: an IDLInterface instance. It is assumed that all types have
1839 been converted to Dart types (e.g. int, String), unless they are in
1840 the same package as the interface.
1841 super_interface: A string or None, the name of the common interface that
1842 this interface implements, if any.
1843 dart_code: an Emitter for the file containing the Dart implementation
1844 class.
1845 shared: functionaly shared across all Html generators.
1846 """
1847 self._system = system
1848 self._interface = interface
1849 self._super_interface = super_interface
1850 self._dart_code = dart_code
1851 self._current_secondary_parent = None
1852 self._shared = shared
1853 self._template = template
1854
1855 def NativeObjectName(self):
1856 return '_ptr'
1857
1858 def StartInterface(self):
1859 interface = self._interface
1860 interface_name = interface.id
1861 self._class_name = self._ImplClassName(interface_name)
1862
1863 self._members_emitter = self._dart_code.Emit(self._template,
1864 NAME=interface_name,
1865 CLASSNAME=self._class_name,
1866 POINTER=self.NativeObjectName(),
1867 LOCAL=_cross_frame_wrapped_types[interface_name][1]
1868 )
1869
1870 def _ImplClassName(self, type_name):
1871 return self._shared._ImplClassName(type_name)
1872
1873 def FinishInterface(self):
1874 """."""
1875 pass
1876
1877 def AddConstant(self, constant):
1878 # Constants are already defined on the interface.
1879 pass
1880
1881 def AddAttribute(self, getter, setter):
1882 dom_name = DartDomNameOfAttribute(getter or setter)
1883 html_getter_name = self._shared.RenameInHtmlLibrary(
1884 self._interface, dom_name, 'get:', implementation_class=True)
1885 html_setter_name = self._shared.RenameInHtmlLibrary(
1886 self._interface, dom_name, 'set:', implementation_class=True)
1887
1888 # TODO(vsm): Generate stubs that throws an error if getter or
1889 # setter is suppressed.
1890 if (getter and html_getter_name and
1891 ('DoNotCheckSecurityOnGetter' in getter.ext_attrs or
1892 'DoNotCheckSecurity' in getter.ext_attrs)):
1893 self._AddGetter(getter, html_getter_name)
1894 if (setter and html_setter_name and
1895 ('DoNotCheckSecurityOnSetter' in setter.ext_attrs or
1896 'DoNotCheckSecurity' in setter.ext_attrs)):
1897 self._AddSetter(setter, html_setter_name)
1898
1899 def _AddGetter(self, attr, html_name):
1900 self._members_emitter.Emit(
1901 '\n'
1902 ' $TYPE get $(NAME)() => $(THIS).$NAME;\n',
1903 NAME=html_name,
1904 TYPE=DartType(attr.type.id),
1905 THIS=self.NativeObjectName())
1906
1907 def _AddSetter(self, attr, html_name):
1908 self._members_emitter.Emit(
1909 '\n'
1910 ' void set $(NAME)($TYPE value) { '
1911 '$(THIS).$NAME = value; }\n',
1912 NAME=html_name,
1913 TYPE=DartType(attr.type.id),
1914 THIS=self.NativeObjectName())
1915
1916 def AddSecondaryAttribute(self, interface, getter, setter):
1917 pass
1918
1919 def AddSecondaryOperation(self, interface, info):
1920 pass
1921
1922 def AddEventAttributes(self, event_attrs):
1923 pass
1924
1925 def AddIndexer(self, element_type):
1926 """Adds all the methods required to complete implementation of List."""
1927 raise Exception('Indexers not yet supported for cross frame types')
1928
1929 def AddOperation(self, info):
1930 """
1931 Arguments:
1932 info: An OperationInfo object.
1933 """
1934 if 'DoNotCheckSecurity' not in info.overloads[0].ext_attrs:
1935 # TODO(vsm): Generate stub that throws an error.
1936 return
1937
1938 html_name = self._shared.RenameInHtmlLibrary(
1939 self._interface, info.name, implementation_class=True)
1940
1941 if not html_name:
1942 return
1943
1944 body = self._members_emitter.Emit(
1945 '\n'
1946 ' $TYPE $NAME($PARAMS) {\n'
1947 '$!BODY'
1948 ' }\n',
1949 TYPE=info.type_name,
1950 NAME=html_name,
1951 PARAMS=info.ParametersImplementationDeclaration())
1952
1953 # Process in order of ascending number of arguments to ensure missing
1954 # optional arguments are processed early.
1955 overloads = sorted(info.overloads,
1956 key=lambda overload: len(overload.arguments))
1957 self._native_version = 0
1958 fallthrough = self.GenerateDispatch(body, info, ' ', 0, overloads)
1959 if fallthrough:
1960 body.Emit(' throw "Incorrect number or type of arguments";\n');
1961
1962 def GenerateSingleOperation(self, emitter, info, indent, operation):
sra1 2012/05/10 00:12:06 We really need to avoid another copy of the dispat
1963 """Generates a call to a single operation.
1964
1965 Arguments:
1966 emitter: an Emitter for the body of a block of code.
1967 info: the compound information about the operation and its overloads.
1968 indent: an indentation string for generated code.
1969 operation: the IDLOperation to call.
1970 """
1971 argument_expressions = ', '.join([i.name for i in info.param_infos])
1972
1973 if info.type_name != 'void':
1974 # We could place the logic for handling Document directly in _wrap
1975 # but we chose to place it here so that bugs in the wrapper and
1976 # wrapperless implementations are more consistent.
1977 emitter.Emit('$(INDENT)return $(THIS).$NAME($ARGS);\n',
1978 INDENT=indent,
1979 THIS=self.NativeObjectName(),
1980 NAME=info.name,
1981 ARGS=argument_expressions)
1982 else:
1983 emitter.Emit('$(INDENT)$(THIS).$NAME($ARGS);\n'
1984 '$(INDENT)return;\n',
1985 INDENT=indent,
1986 THIS=self.NativeObjectName(),
1987 NAME=info.name,
1988 ARGS=argument_expressions)
1989
1990 def GenerateDispatch(self, emitter, info, indent, position, overloads):
1991 """Generates a dispatch to one of the overloads.
1992
1993 Arguments:
1994 emitter: an Emitter for the body of a block of code.
1995 info: the compound information about the operation and its overloads.
1996 indent: an indentation string for generated code.
1997 position: the index of the parameter to dispatch on.
1998 overloads: a list of the remaining IDLOperations to dispatch.
1999
2000 Returns True if the dispatch can fall through on failure, False if the code
2001 always dispatches.
2002 """
2003
2004 def NullCheck(name):
2005 return '%s === null' % name
2006
2007 def TypeCheck(name, type):
2008 return '%s is %s' % (name, type)
2009
2010 if position == len(info.param_infos):
2011 if len(overloads) > 1:
2012 raise Exception('Duplicate operations ' + str(overloads))
2013 operation = overloads[0]
2014 self.GenerateSingleOperation(emitter, info, indent, operation)
2015 return False
2016
2017 # FIXME: Consider a simpler dispatch that iterates over the
2018 # overloads and generates an overload specific check. Revisit
2019 # when we move to named optional arguments.
2020
2021 # Partition the overloads to divide and conquer on the dispatch.
2022 positive = []
2023 negative = []
2024 first_overload = overloads[0]
2025 param = info.param_infos[position]
2026
2027 if position < len(first_overload.arguments):
2028 # FIXME: This will not work if the second overload has a more
2029 # precise type than the first. E.g.,
2030 # void foo(Node x);
2031 # void foo(Element x);
2032 type = DartType(first_overload.arguments[position].type.id)
2033 test = TypeCheck(param.name, type)
2034 pred = lambda op: (len(op.arguments) > position and
2035 DartType(op.arguments[position].type.id) == type)
2036 else:
2037 type = None
2038 test = NullCheck(param.name)
2039 pred = lambda op: position >= len(op.arguments)
2040
2041 for overload in overloads:
2042 if pred(overload):
2043 positive.append(overload)
2044 else:
2045 negative.append(overload)
2046
2047 if positive and negative:
2048 (true_code, false_code) = emitter.Emit(
2049 '$(INDENT)if ($COND) {\n'
2050 '$!TRUE'
2051 '$(INDENT)} else {\n'
2052 '$!FALSE'
2053 '$(INDENT)}\n',
2054 COND=test, INDENT=indent)
2055 fallthrough1 = self.GenerateDispatch(
2056 true_code, info, indent + ' ', position + 1, positive)
2057 fallthrough2 = self.GenerateDispatch(
2058 false_code, info, indent + ' ', position, negative)
2059 return fallthrough1 or fallthrough2
2060
2061 if negative:
2062 raise Exception('Internal error, must be all positive')
2063
2064 # All overloads require the same test. Do we bother?
2065
2066 # If the test is the same as the method's formal parameter then checked mode
2067 # will have done the test already. (It could be null too but we ignore that
2068 # case since all the overload behave the same and we don't know which types
2069 # in the IDL are not nullable.)
2070 if type == param.dart_type:
2071 return self.GenerateDispatch(
2072 emitter, info, indent, position + 1, positive)
2073
2074 # Otherwise the overloads have the same type but the type is a substype of
2075 # the method's synthesized formal parameter. e.g we have overloads f(X) and
2076 # f(Y), implemented by the synthesized method f(Z) where X<Z and Y<Z. The
2077 # dispatch has removed f(X), leaving only f(Y), but there is no guarantee
2078 # that Y = Z-X, so we need to check for Y.
2079 true_code = emitter.Emit(
2080 '$(INDENT)if ($COND) {\n'
2081 '$!TRUE'
2082 '$(INDENT)}\n',
2083 COND=test, INDENT=indent)
2084 self.GenerateDispatch(
2085 true_code, info, indent + ' ', position + 1, positive)
2086 return True
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698