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 from generator import AnalyzeOperation, ConstantOutputOrder, \ | 10 from generator import AnalyzeOperation, ConstantOutputOrder, \ |
11 DartDomNameOfAttribute, FindMatchingAttribute, IsDartCollectionType, \ | 11 DartDomNameOfAttribute, FindMatchingAttribute, IsDartCollectionType, \ |
12 IsPureInterface, TypeOrNothing, ConvertToFuture, GetCallbackInfo | 12 IsPureInterface, TypeOrNothing, ConvertToFuture, GetCallbackInfo |
13 from copy import deepcopy | |
13 from htmlrenamer import convert_to_future_members | 14 from htmlrenamer import convert_to_future_members |
15 import monitored | |
14 | 16 |
15 # Types that are accessible cross-frame in a limited fashion. | 17 # Types that are accessible cross-frame in a limited fashion. |
16 # In these cases, the base type (e.g., WindowBase) provides restricted access | 18 # In these cases, the base type (e.g., WindowBase) provides restricted access |
17 # while the subtype (e.g., Window) provides full access to the | 19 # while the subtype (e.g., Window) provides full access to the |
18 # corresponding objects if there are from the same frame. | 20 # corresponding objects if there are from the same frame. |
19 _secure_base_types = { | 21 _secure_base_types = { |
20 'Window': 'WindowBase', | 22 'Window': 'WindowBase', |
21 'Location': 'LocationBase', | 23 'Location': 'LocationBase', |
22 'History': 'HistoryBase', | 24 'History': 'HistoryBase', |
23 } | 25 } |
24 | 26 |
25 _custom_factories = [ | 27 _custom_factories = [ |
26 'Notification', | 28 'Notification', |
27 'EventSource', | 29 'EventSource', |
28 ] | 30 ] |
29 | 31 |
32 # Members that have multiple definitions, but their types are vary, so we rename | |
33 # them to make them distinct. | |
34 _renamed_overloads = monitored.Dict('htmldartgenreator.renamed_overloads', { | |
blois
2013/06/24 16:58:02
Could this go to htmlrenamer, just to keep our ren
Emily Fortuna
2013/06/25 03:53:31
Done.
| |
35 'AudioContext.createBuffer(unsigned long numberOfChannels, unsigned long ' | |
36 'numberOfFrames, float sampleRate)': 'createEmptyBuffer', | |
37 'AudioContext.createBuffer(ArrayBuffer buffer, boolean mixToMono)': | |
38 'createBufferFromBuffer', | |
39 'CSS.supports(DOMString conditionText)': 'supportsCondition', | |
40 'CSS.supports(DOMString property, DOMString value)': 'supportsProperty', | |
41 'CanvasRenderingContext2D.createPattern(HTMLCanvasElement canvas, ' | |
42 'DOMString repetitionType)': 'createPatternFromCanvas', | |
43 'CanvasRenderingContext2D.createPattern(HTMLImageElement image, ' | |
44 'DOMString repetitionType)': 'createPatternFromImage', | |
45 'DataTransferItemList.add(File file)': 'addFile', | |
46 'DataTransferItemList.add(DOMString data, DOMString type)': 'addData', | |
47 'FormData.append(DOMString name, DOMString value)': 'appendString', | |
48 'FormData.append(DOMString name, Blob value, DOMString filename)': | |
49 'appendBlob', | |
50 'IDBDatabase.transaction(DOMStringList storeNames, DOMString mode)': | |
51 'transactionStringList', | |
52 'IDBDatabase.transaction(sequence<DOMString> storeNames, DOMString mode)': | |
53 'transactionList', | |
54 'IDBDatabase.transaction(DOMString storeName, DOMString mode)': | |
55 'transactionString', | |
56 'RTCDataChannel.send(ArrayBuffer data)': 'sendByteBuffer', | |
57 'RTCDataChannel.send(ArrayBufferView data)': 'sendTypedData', | |
58 'RTCDataChannel.send(Blob data)': 'sendBlob', | |
59 'RTCDataChannel.send(DOMString data)': 'sendString', | |
60 'URL.createObjectURL(WebKitMediaSource source)': | |
61 'createObjectUrlFromSource', | |
62 'URL.createObjectURL(MediaStream stream)': 'createObjectUrlFromStream', | |
63 'URL.createObjectURL(Blob blob)': 'createObjectUrlFromBlob', | |
64 'WebGLRenderingContext.texImage2D(unsigned long target, long level, ' | |
65 'unsigned long internalformat, unsigned long format, unsigned long ' | |
66 'type, ImageData pixels)': 'texImage2DData', | |
67 'WebGLRenderingContext.texImage2D(unsigned long target, long level, ' | |
68 'unsigned long internalformat, unsigned long format, unsigned long ' | |
69 'type, HTMLImageElement image)': 'texImage2DImage', | |
70 'WebGLRenderingContext.texImage2D(unsigned long target, long level, ' | |
71 'unsigned long internalformat, unsigned long format, unsigned long ' | |
72 'type, HTMLCanvasElement canvas)': 'texImage2DCanvas', | |
73 'WebGLRenderingContext.texImage2D(unsigned long target, long level, ' | |
74 'unsigned long internalformat, unsigned long format, unsigned long ' | |
75 'type, HTMLVideoElement video)': 'texImage2DVideo', | |
76 'WebGLRenderingContext.texSubImage2D(unsigned long target, long level, ' | |
77 'long xoffset, long yoffset, unsigned long format, unsigned long type, ' | |
78 'ImageData pixels)': 'texSubImage2DData', | |
79 'WebGLRenderingContext.texSubImage2D(unsigned long target, long level, ' | |
80 'long xoffset, long yoffset, unsigned long format, unsigned long type, ' | |
81 'HTMLImageElement image)': 'texSubImage2DImage', | |
82 'WebGLRenderingContext.texSubImage2D(unsigned long target, long level, ' | |
83 'long xoffset, long yoffset, unsigned long format, unsigned long type, ' | |
84 'HTMLCanvasElement canvas)': 'texSubImage2DCanvas', | |
85 'WebGLRenderingContext.texSubImage2D(unsigned long target, long level, ' | |
86 'long xoffset, long yoffset, unsigned long format, unsigned long type, ' | |
87 'HTMLVideoElement video)': 'texSubImage2DVideo', | |
88 'WebGLRenderingContext.bufferData(unsigned long target, ' | |
89 'ArrayBufferView data, unsigned long usage)': 'bufferTypedData', | |
90 'WebGLRenderingContext.bufferData(unsigned long target, long long size, ' | |
91 'unsigned long usage)': 'bufferEmptyData', | |
92 'WebGLRenderingContext.bufferSubData(unsigned long target, ' | |
93 'long long offset, ArrayBufferView data)': 'bufferSubTypedData', | |
94 'WebSocket.send(ArrayBuffer data)': 'sendByteBuffer', | |
95 'WebSocket.send(ArrayBufferView data)': 'sendTypeData', | |
96 'WebSocket.send(DOMString data)': 'sendString', | |
97 'WebSocket.send(Blob data)': 'sendBlob' | |
98 }) | |
99 | |
30 class HtmlDartGenerator(object): | 100 class HtmlDartGenerator(object): |
31 def __init__(self, interface, options): | 101 def __init__(self, interface, options): |
32 self._database = options.database | 102 self._database = options.database |
33 self._interface = interface | 103 self._interface = interface |
34 self._type_registry = options.type_registry | 104 self._type_registry = options.type_registry |
35 self._interface_type_info = self._type_registry.TypeInfo(self._interface.id) | 105 self._interface_type_info = self._type_registry.TypeInfo(self._interface.id) |
36 self._renamer = options.renamer | 106 self._renamer = options.renamer |
37 self._metadata = options.metadata | 107 self._metadata = options.metadata |
38 self._library_name = self._renamer.GetLibraryName(self._interface) | 108 self._library_name = self._renamer.GetLibraryName(self._interface) |
39 | 109 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
76 else: | 146 else: |
77 for parent in self._database.Hierarchy(self._interface): | 147 for parent in self._database.Hierarchy(self._interface): |
78 if parent == self._interface: | 148 if parent == self._interface: |
79 continue | 149 continue |
80 parent_type_info = self._type_registry.TypeInfo(parent.id) | 150 parent_type_info = self._type_registry.TypeInfo(parent.id) |
81 if parent_type_info.list_item_type(): | 151 if parent_type_info.list_item_type(): |
82 self.AmendIndexer(parent_type_info.list_item_type()) | 152 self.AmendIndexer(parent_type_info.list_item_type()) |
83 break | 153 break |
84 | 154 |
85 # Group overloaded operations by name. | 155 # Group overloaded operations by name. |
156 self._AddRenamedOverloads(interface) | |
86 operationsByName = self._OperationsByName(interface) | 157 operationsByName = self._OperationsByName(interface) |
87 | 158 |
88 # Generate operations. | 159 # Generate operations. |
89 for id in sorted(operationsByName.keys()): | 160 for id in sorted(operationsByName.keys()): |
90 operations = operationsByName[id] | 161 operations = operationsByName[id] |
91 info = AnalyzeOperation(interface, operations) | 162 info = AnalyzeOperation(interface, operations) |
92 self.AddOperation(info, declare_only) | 163 self.AddOperation(info, declare_only) |
93 if ('%s.%s' % (interface.id, info.declared_name) in | 164 if ('%s.%s' % (interface.id, info.declared_name) in |
94 convert_to_future_members): | 165 convert_to_future_members): |
95 self.AddOperation(ConvertToFuture(info), declare_only) | 166 self.AddOperation(ConvertToFuture(info), declare_only) |
(...skipping 16 matching lines...) Expand all Loading... | |
112 operationsByName =self._OperationsByName(parent_interface) | 183 operationsByName =self._OperationsByName(parent_interface) |
113 | 184 |
114 # Generate operations. | 185 # Generate operations. |
115 for id in sorted(operationsByName.keys()): | 186 for id in sorted(operationsByName.keys()): |
116 if not any(op.id == id for op in interface.operations): | 187 if not any(op.id == id for op in interface.operations): |
117 operations = operationsByName[id] | 188 operations = operationsByName[id] |
118 info = AnalyzeOperation(interface, operations) | 189 info = AnalyzeOperation(interface, operations) |
119 self.SecondaryContext(parent_interface) | 190 self.SecondaryContext(parent_interface) |
120 self.AddOperation(info) | 191 self.AddOperation(info) |
121 | 192 |
193 def _AddRenamedOverloads(self, interface): | |
194 """The IDL has a number of functions with the same name but that accept | |
195 different types. This is fine for JavaScript, but results in vague type | |
196 signatures for Dart. We rename some of these (by adding a new identical | |
197 operation with a different DartName), but leave the original version as | |
198 well.""" | |
199 # This function gets called twice per interface if we generate both dart2js | |
blois
2013/06/24 16:58:02
Is there a more central place we can do this, so i
Emily Fortuna
2013/06/25 03:53:31
Not really if we do it in the python scripts, unle
| |
200 # and dartium APIs, but we only want to rename the overloads once, so we | |
201 # keep track of this via already_renamed. | |
202 already_renamed = [operation.ext_attrs['DartName'] if 'DartName' in | |
blois
2013/06/24 16:58:02
Doesn't have to be in this CL, but we should remov
| |
203 operation.ext_attrs else '' for operation in interface.operations] | |
204 added_operations = [] | |
205 for operation in interface.operations: | |
blois
2013/06/24 16:58:02
Are there any warnings when there are overloads th
Emily Fortuna
2013/06/25 03:53:31
added a warning output, but it's not super useful
| |
206 if (self._GetStringRepresentation( | |
207 interface, operation) in _renamed_overloads and _renamed_overloads[ | |
208 self._GetStringRepresentation(interface, operation)] not in | |
209 already_renamed): | |
210 cloned_operation = deepcopy(operation) | |
211 cloned_operation.ext_attrs['DartName'] = _renamed_overloads[ | |
212 self._GetStringRepresentation(interface, operation)] | |
213 added_operations.append(cloned_operation) | |
214 interface.operations += added_operations | |
215 | |
216 def _GetStringRepresentation(self, interface, operation): | |
217 """Given an IDLOperation, return a object-independent representation of the | |
218 operations's signature.""" | |
219 return '%s.%s(%s)' % (interface.id, operation.id, ', '.join( | |
220 ['%s %s' % (arg.type.id, arg.id) for arg in operation.arguments])) | |
221 | |
122 def _OperationsByName(self, interface): | 222 def _OperationsByName(self, interface): |
123 operationsByName = {} | 223 operationsByName = {} |
124 for operation in interface.operations: | 224 for operation in interface.operations: |
125 name = operation.ext_attrs.get('DartName', operation.id) | 225 name = operation.ext_attrs.get('DartName', operation.id) |
126 operationsByName.setdefault(name, []).append(operation) | 226 operationsByName.setdefault(name, []).append(operation) |
127 return operationsByName | 227 return operationsByName |
128 | 228 |
129 def AddConstant(self, constant): | 229 def AddConstant(self, constant): |
130 const_name = self._renamer.RenameMember( | 230 const_name = self._renamer.RenameMember( |
131 self._interface.id, constant, constant.id, 'get:', dartify_name=False) | 231 self._interface.id, constant, constant.id, 'get:', dartify_name=False) |
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
585 if interface.parents: | 685 if interface.parents: |
586 parent = interface.parents[0] | 686 parent = interface.parents[0] |
587 if IsPureInterface(parent.type.id): | 687 if IsPureInterface(parent.type.id): |
588 walk(interface.parents) | 688 walk(interface.parents) |
589 else: | 689 else: |
590 walk(interface.parents[1:]) | 690 walk(interface.parents[1:]) |
591 return result | 691 return result |
592 | 692 |
593 def _DartType(self, type_name): | 693 def _DartType(self, type_name): |
594 return self._type_registry.DartType(type_name) | 694 return self._type_registry.DartType(type_name) |
OLD | NEW |