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 systems to generate | 6 """This module provides shared functionality for systems to generate |
7 Dart APIs from the IDL database.""" | 7 Dart APIs from the IDL database.""" |
8 | 8 |
9 import copy | 9 import copy |
10 import json | 10 import json |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 'NodeList': 'NodeList,RadioNodeList', | 160 'NodeList': 'NodeList,RadioNodeList', |
161 | 161 |
162 'OscillatorNode': 'OscillatorNode,Oscillator', | 162 'OscillatorNode': 'OscillatorNode,Oscillator', |
163 | 163 |
164 'PannerNode': 'PannerNode,AudioPannerNode,webkitAudioPannerNode', | 164 'PannerNode': 'PannerNode,AudioPannerNode,webkitAudioPannerNode', |
165 | 165 |
166 'RTCPeerConnection': 'RTCPeerConnection,mozRTCPeerConnection', | 166 'RTCPeerConnection': 'RTCPeerConnection,mozRTCPeerConnection', |
167 | 167 |
168 'RTCIceCandidate': 'RTCIceCandidate,mozRTCIceCandidate', | 168 'RTCIceCandidate': 'RTCIceCandidate,mozRTCIceCandidate', |
169 | 169 |
170 'RTCIceCandidateEvent': 'RTCIceCandidateEvent,RTCPeerConnectionIceEvent', | 170 'RTCIceCandidateEvent': 'RTCIceCandidateEvent,RTCPeerConnectionIceEvent', |
171 | 171 |
172 'RTCSessionDescription': 'RTCSessionDescription,mozRTCSessionDescription', | 172 'RTCSessionDescription': 'RTCSessionDescription,mozRTCSessionDescription', |
173 | 173 |
174 'RTCDataChannel': 'RTCDataChannel,DataChannel', | 174 'RTCDataChannel': 'RTCDataChannel,DataChannel', |
175 | 175 |
176 'ScriptProcessorNode': 'ScriptProcessorNode,JavaScriptAudioNode', | 176 'ScriptProcessorNode': 'ScriptProcessorNode,JavaScriptAudioNode', |
177 | 177 |
178 'TransitionEvent': 'TransitionEvent,WebKitTransitionEvent', | 178 'TransitionEvent': 'TransitionEvent,WebKitTransitionEvent', |
179 | 179 |
180 'WebGLLoseContext': 'WebGLLoseContext,WebGLExtensionLoseContext', | 180 'WebGLLoseContext': 'WebGLLoseContext,WebGLExtensionLoseContext', |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 def param_name(param_info): | 507 def param_name(param_info): |
508 if self.requires_named_arguments and param_info.is_optional: | 508 if self.requires_named_arguments and param_info.is_optional: |
509 return '%s : %s' % (param_info.name, param_info.name) | 509 return '%s : %s' % (param_info.name, param_info.name) |
510 else: | 510 else: |
511 return param_info.name | 511 return param_info.name |
512 | 512 |
513 if parameter_count is None: | 513 if parameter_count is None: |
514 parameter_count = len(self.param_infos) | 514 parameter_count = len(self.param_infos) |
515 return ', '.join(map(param_name, self.param_infos[:parameter_count])) | 515 return ', '.join(map(param_name, self.param_infos[:parameter_count])) |
516 | 516 |
517 def wrap_unwrap_list_blink(self, return_type, type_registry): | 517 def isCallback(self, type_registry, type_id): |
518 """Return True if the type is a List<Node>""" | 518 if type_id: |
519 return return_type.startswith('List<Node>') | 519 callback_type = type_registry._database._all_interfaces[type_id] |
520 | 520 return callback_type.operations[0].id == 'handleEvent' if len(callback_typ
e.operations) > 0 else False |
521 def wrap_unwrap_type_blink(self, return_type, type_registry): | 521 else: |
522 """Returns True if the type is a blink type that requires wrap_jso or unwrap
_jso. | 522 return False |
523 Notice we look for any class that starts with HtmlNNNN e.g., HtmlDocument, e
tc. """ | |
524 return (type_registry.HasInterface(return_type) or not(return_type) or | |
525 return_type == 'Object' or return_type.startswith('Html') or | |
526 return_type == 'MutationObserver') | |
527 | 523 |
528 def ParametersAsListOfVariables(self, parameter_count=None, type_registry=None
, dart_js_interop=False): | 524 def ParametersAsListOfVariables(self, parameter_count=None, type_registry=None
, dart_js_interop=False): |
529 """Returns a list of the first parameter_count parameter names | 525 """Returns a list of the first parameter_count parameter names |
530 as raw variables. | 526 as raw variables. |
531 """ | 527 """ |
| 528 isRemoveOperation = self.name == 'removeEventListener' or self.name == 'remo
veListener' |
| 529 |
532 if parameter_count is None: | 530 if parameter_count is None: |
533 parameter_count = len(self.param_infos) | 531 parameter_count = len(self.param_infos) |
534 if not type_registry: | 532 if not type_registry: |
535 return [p.name for p in self.param_infos[:parameter_count]] | 533 return [p.name for p in self.param_infos[:parameter_count]] |
536 else: | 534 else: |
537 parameters = [] | 535 parameters = [] |
538 for p in self.param_infos[:parameter_count]: | 536 for p in self.param_infos[:parameter_count]: |
539 type_id = p.type_id | 537 type_id = p.type_id |
540 # Unwrap the type to get the JsObject if Type is: | 538 # Unwrap the type to get the JsObject if Type is: |
541 # | 539 # |
542 # - known IDL type | 540 # - known IDL type |
543 # - type_id is None then it's probably a union type or overloaded | 541 # - type_id is None then it's probably a union type or overloaded |
544 # it's a dynamic/any type | 542 # it's a dynamic/any type |
545 # - type is Object | 543 # - type is Object |
546 # | 544 # |
547 # JsObject maybe stored in the Dart class. | 545 # JsObject maybe stored in the Dart class. |
548 if (self.wrap_unwrap_type_blink(type_id, type_registry)): | 546 if (wrap_unwrap_type_blink(type_id, type_registry)): |
549 if dart_js_interop and type_id == 'EventListener' and (self.name == 'a
ddEventListener' or | 547 type_is_callback = self.isCallback(type_registry, type_id) |
550 self.name == 'a
ddListener'): | 548 if (dart_js_interop and type_id == 'EventListener' and |
551 # Events fired need to wrap the Javascript Object passed as a parame
ter in event. | 549 (self.name == 'addEventListener')): |
552 parameters.append('unwrap_jso((Event event) => %s(wrap_jso(event)))'
% p.name) | 550 # Events fired need use a JsFunction not a anonymous closure to |
| 551 # insure the event can really be removed. |
| 552 parameters.append('wrap_event_listener(this, %s)' % p.name) |
| 553 elif (dart_js_interop and type_id == 'EventListener' and |
| 554 (self.name == 'removeEventListener')): |
| 555 # Find the JsFunction that corresponds to this Dart function. |
| 556 parameters.append('_knownListeners[this.hashCode][identityHashCode
(%s)]' % p.name) |
| 557 elif dart_js_interop and type_id == 'FontFaceSetForEachCallback': |
| 558 # forEach is supported in the DOM for FontFaceSet as it iterates |
| 559 # over the Javascript Object the callback parameters are also |
| 560 # Javascript objects and must be wrapped. |
| 561 parameters.append('unwrap_jso((fontFace, fontFaceAgain, set) => %s
(wrap_jso(fontFace), wrap_jso(fontFaceAgain), wrap_jso(set)))' % p.name) |
| 562 elif dart_js_interop and type_id == 'HeadersForEachCallback': |
| 563 # forEach is supported in the DOM for Headers as it iterates |
| 564 # over the Javascript Object the callback parameters are also |
| 565 # Javascript objects and must be wrapped. |
| 566 parameters.append('unwrap_jso((String value, String key, map) => %
s(value, key, wrap_jso(map)))' % p.name) |
| 567 elif dart_js_interop and type_is_callback and not(isRemoveOperation): |
| 568 # Any remove operation that has a a callback doesn't need wrapping. |
| 569 # TODO(terry): Kind of hacky but handles all the cases we care about |
| 570 callback_type = type_registry._database._all_interfaces[type_id] |
| 571 callback_args_decl = [] |
| 572 callback_args_call = [] |
| 573 for callback_arg in callback_type.operations[0].arguments: |
| 574 if dart_js_interop: |
| 575 dart_type = '' # For non-primitives we will be passing JsObject
for non-primitives, so ignore types |
| 576 else: |
| 577 dart_type = type_registry.DartType(callback_arg.type.id) + ' ' |
| 578 callback_args_decl.append('%s%s' % (dart_type, callback_arg.id)) |
| 579 if wrap_unwrap_type_blink(callback_arg.type.id, type_registry): |
| 580 callback_args_call.append('wrap_jso(%s)' % callback_arg.id) |
| 581 else: |
| 582 callback_args_call.append(callback_arg.id) |
| 583 parameters.append('unwrap_jso((%s) => %s(%s))' % |
| 584 (", ".join(callback_args_decl), |
| 585 p.name, |
| 586 ", ".join(callback_args_call))) |
553 else: | 587 else: |
554 parameters.append('unwrap_jso(%s)' % p.name) | 588 parameters.append('unwrap_jso(%s)' % p.name) |
555 else: | 589 else: |
556 if dart_js_interop: | 590 if dart_js_interop: |
557 passParam = p.name | 591 passParam = p.name |
558 if type_id == 'Dictionary': | 592 if type_id == 'Dictionary': |
559 # Need to pass the IDL Dictionary from Dart Map to JavaScript obje
ct. | 593 # Need to pass the IDL Dictionary from Dart Map to JavaScript obje
ct. |
560 passParam = '{0} != null ? new js.JsObject.jsify({0}) : {0}'.forma
t(p.name) | 594 passParam = '{0} != null ? new js.JsObject.jsify({0}) : {0}'.forma
t(p.name) |
561 else: | 595 else: |
562 passParam = p.name | 596 passParam = p.name |
(...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1389 if type_data.clazz == 'BasicTypedList': | 1423 if type_data.clazz == 'BasicTypedList': |
1390 if type_name == 'ArrayBuffer': | 1424 if type_name == 'ArrayBuffer': |
1391 dart_interface_name = 'ByteBuffer' | 1425 dart_interface_name = 'ByteBuffer' |
1392 else: | 1426 else: |
1393 dart_interface_name = self._renamer.RenameInterfaceId(type_name) | 1427 dart_interface_name = self._renamer.RenameInterfaceId(type_name) |
1394 return BasicTypedListIDLTypeInfo( | 1428 return BasicTypedListIDLTypeInfo( |
1395 type_name, type_data, dart_interface_name, self) | 1429 type_name, type_data, dart_interface_name, self) |
1396 | 1430 |
1397 class_name = '%sIDLTypeInfo' % type_data.clazz | 1431 class_name = '%sIDLTypeInfo' % type_data.clazz |
1398 return globals()[class_name](type_name, type_data) | 1432 return globals()[class_name](type_name, type_data) |
| 1433 |
| 1434 def wrap_unwrap_list_blink(return_type, type_registry): |
| 1435 """Return True if the type is a List<Node>""" |
| 1436 return return_type.startswith('List<Node>') |
| 1437 |
| 1438 def wrap_unwrap_type_blink(return_type, type_registry): |
| 1439 """Returns True if the type is a blink type that requires wrap_jso or |
| 1440 unwrap_jso""" |
| 1441 if return_type and return_type.startswith('Html'): |
| 1442 return_type = return_type.replace('Html', 'HTML', 1) |
| 1443 return (type_registry.HasInterface(return_type) or not(return_type) or |
| 1444 return_type == 'Object' or |
| 1445 return_type == 'Future' or |
| 1446 return_type == 'SqlDatabase' or # renamed to Database |
| 1447 return_type == 'HTMLElement' or |
| 1448 return_type == 'MutationObserver') |
| 1449 |
| 1450 def wrap_type_blink(return_type, type_registry): |
| 1451 """Returns True if the type is a blink type that requires wrap_jso but |
| 1452 NOT unwrap_jso""" |
| 1453 return (return_type == 'Map' or |
| 1454 return_type == 'Rectangle') |
| 1455 |
| 1456 def wrap_return_type_blink(return_type, type_name, type_registry): |
| 1457 """Returns True if we should wrap the returned value. This checks |
| 1458 a number of different variations, calling the more basic functions |
| 1459 above.""" |
| 1460 return (wrap_unwrap_type_blink(return_type, type_registry) or |
| 1461 wrap_unwrap_type_blink(type_name, type_registry) or |
| 1462 wrap_type_blink(return_type, type_registry) or |
| 1463 wrap_unwrap_list_blink(return_type, type_registry)) |
OLD | NEW |