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, GetAnnotationsAndComments, \ | 12 IsPureInterface, TypeOrNothing, GetAnnotationsAndComments, \ |
13 FormatAnnotationsAndComments | 13 FormatAnnotationsAndComments, ConvertToFuture, GetCallbackInfo |
| 14 from htmlrenamer import convert_to_future_members |
14 | 15 |
15 # Types that are accessible cross-frame in a limited fashion. | 16 # Types that are accessible cross-frame in a limited fashion. |
16 # In these cases, the base type (e.g., WindowBase) provides restricted access | 17 # In these cases, the base type (e.g., WindowBase) provides restricted access |
17 # while the subtype (e.g., Window) provides full access to the | 18 # while the subtype (e.g., Window) provides full access to the |
18 # corresponding objects if there are from the same frame. | 19 # corresponding objects if there are from the same frame. |
19 _secure_base_types = { | 20 _secure_base_types = { |
20 'Window': 'WindowBase', | 21 'Window': 'WindowBase', |
21 'Location': 'LocationBase', | 22 'Location': 'LocationBase', |
22 'History': 'HistoryBase', | 23 'History': 'HistoryBase', |
23 } | 24 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 for operation in interface.operations: | 83 for operation in interface.operations: |
83 if operation.id not in operationsById: | 84 if operation.id not in operationsById: |
84 operationsById[operation.id] = [] | 85 operationsById[operation.id] = [] |
85 operationsById[operation.id].append(operation) | 86 operationsById[operation.id].append(operation) |
86 | 87 |
87 # Generate operations. | 88 # Generate operations. |
88 for id in sorted(operationsById.keys()): | 89 for id in sorted(operationsById.keys()): |
89 operations = operationsById[id] | 90 operations = operationsById[id] |
90 info = AnalyzeOperation(interface, operations) | 91 info = AnalyzeOperation(interface, operations) |
91 self.AddOperation(info, declare_only) | 92 self.AddOperation(info, declare_only) |
| 93 if ('%s.%s' % (interface.id, info.declared_name) in |
| 94 convert_to_future_members): |
| 95 self.AddOperation(ConvertToFuture(info), declare_only) |
92 | 96 |
93 def AddSecondaryMembers(self, interface): | 97 def AddSecondaryMembers(self, interface): |
94 # With multiple inheritance, attributes and operations of non-first | 98 # With multiple inheritance, attributes and operations of non-first |
95 # interfaces need to be added. Sometimes the attribute or operation is | 99 # interfaces need to be added. Sometimes the attribute or operation is |
96 # defined in the current interface as well as a parent. In that case we | 100 # defined in the current interface as well as a parent. In that case we |
97 # avoid making a duplicate definition and pray that the signatures match. | 101 # avoid making a duplicate definition and pray that the signatures match. |
98 secondary_parents = self._TransitiveSecondaryParents(interface) | 102 secondary_parents = self._TransitiveSecondaryParents(interface) |
99 for parent_interface in sorted(secondary_parents): | 103 for parent_interface in sorted(secondary_parents): |
100 if isinstance(parent_interface, str): | 104 if isinstance(parent_interface, str): |
101 continue | 105 continue |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 constructor_info.idl_args, | 451 constructor_info.idl_args, |
448 False, | 452 False, |
449 [info.name for info in constructor_info.param_infos], | 453 [info.name for info in constructor_info.param_infos], |
450 emitter.Format('$(ANNOTATIONS)factory $CTOR($PARAMS)', | 454 emitter.Format('$(ANNOTATIONS)factory $CTOR($PARAMS)', |
451 CTOR=constructor_info._ConstructorFullName(self._DartType), | 455 CTOR=constructor_info._ConstructorFullName(self._DartType), |
452 ANNOTATIONS=annotations, | 456 ANNOTATIONS=annotations, |
453 PARAMS=constructor_info.ParametersDeclaration(self._DartType)), | 457 PARAMS=constructor_info.ParametersDeclaration(self._DartType)), |
454 GenerateCall, | 458 GenerateCall, |
455 IsOptional) | 459 IsOptional) |
456 | 460 |
| 461 def _AddFutureifiedOperation(self, info, html_name): |
| 462 """Given a API function that uses callbacks, convert it to using Futures. |
| 463 |
| 464 This conversion assumes the success callback is always provided before the |
| 465 error callback (and so far in the DOM API, this is the case).""" |
| 466 callback_info = GetCallbackInfo( |
| 467 self._database.GetInterface(info.callback_args[0].type_id)) |
| 468 |
| 469 param_list = info.ParametersAsArgumentList() |
| 470 annotations = '' |
| 471 if '_RenamingAnnotation' in dir(self): |
| 472 annotations = (self._RenamingAnnotation(info.declared_name, html_name) + |
| 473 self._Annotations(info.type_name, info.declared_name)) |
| 474 self._members_emitter.Emit( |
| 475 '\n' |
| 476 ' $ANNOTATIONS$MODIFIERS$TYPE$FUTURE_GENERIC $NAME($PARAMS) {\n' |
| 477 ' var completer = new Completer$(FUTURE_GENERIC)();\n' |
| 478 ' $ORIGINAL_FUNCTION($PARAMS_LIST\n' |
| 479 ' $NAMED_PARAM($VARIABLE_NAME) { ' |
| 480 'completer.complete($VARIABLE_NAME); }' |
| 481 '$ERROR_CALLBACK);\n' |
| 482 ' return completer.future;\n' |
| 483 ' }\n', |
| 484 ANNOTATIONS=annotations, |
| 485 MODIFIERS='static ' if info.IsStatic() else '', |
| 486 TYPE=self.SecureOutputType(info.type_name), |
| 487 NAME=html_name[1:], |
| 488 PARAMS=info.ParametersDeclaration(self._NarrowInputType |
| 489 if '_NarrowInputType' in dir(self) else self._DartType), |
| 490 PARAMS_LIST='' if param_list == '' else param_list + ',', |
| 491 NAMED_PARAM=('%s : ' % info.callback_args[0].name |
| 492 if info.requires_named_arguments and |
| 493 info.callback_args[0].is_optional else ''), |
| 494 VARIABLE_NAME= '' if len(callback_info.param_infos) == 0 else 'value', |
| 495 ERROR_CALLBACK=('' if len(info.callback_args) == 1 else |
| 496 (',\n %s(error) { completer.completeError(error); }' % |
| 497 ('%s : ' % info.callback_args[1].name |
| 498 if info.requires_named_arguments and |
| 499 info.callback_args[1].is_optional else ''))), |
| 500 FUTURE_GENERIC = ('' if len(callback_info.param_infos) == 0 or |
| 501 not callback_info.param_infos[0].type_id else |
| 502 '<%s>' % self._DartType(callback_info.param_infos[0].type_id)), |
| 503 ORIGINAL_FUNCTION = html_name) |
| 504 |
457 def EmitHelpers(self, base_class): | 505 def EmitHelpers(self, base_class): |
458 pass | 506 pass |
459 | 507 |
460 def DeclareAttribute(self, attribute, type_name, attr_name, read_only): | 508 def DeclareAttribute(self, attribute, type_name, attr_name, read_only): |
461 """ Declares an attribute but does not include the code to invoke it. | 509 """ Declares an attribute but does not include the code to invoke it. |
462 """ | 510 """ |
463 if read_only: | 511 if read_only: |
464 template = '\n $TYPE get $NAME;\n' | 512 template = '\n $TYPE get $NAME;\n' |
465 else: | 513 else: |
466 template = '\n $TYPE $NAME;\n' | 514 template = '\n $TYPE $NAME;\n' |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 walk(interface.parents) | 603 walk(interface.parents) |
556 else: | 604 else: |
557 walk(interface.parents[1:]) | 605 walk(interface.parents[1:]) |
558 return result | 606 return result |
559 | 607 |
560 def _DartType(self, type_name): | 608 def _DartType(self, type_name): |
561 return self._type_registry.DartType(type_name) | 609 return self._type_registry.DartType(type_name) |
562 | 610 |
563 def _IsPrivate(self, name): | 611 def _IsPrivate(self, name): |
564 return name.startswith('_') | 612 return name.startswith('_') |
OLD | NEW |