| 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 systems to generate | 6 """This module provides shared functionality for the systems to generate |
| 7 native binding from the IDL database.""" | 7 native binding from the IDL database.""" |
| 8 | 8 |
| 9 import emitter | 9 import emitter |
| 10 import os | 10 import os |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 def _EmitEventGetter(self, events_class): | 346 def _EmitEventGetter(self, events_class): |
| 347 self._members_emitter.Emit( | 347 self._members_emitter.Emit( |
| 348 '\n' | 348 '\n' |
| 349 ' $EVENTS_CLASS get on() {\n' | 349 ' $EVENTS_CLASS get on() {\n' |
| 350 ' if (_on === null) _on = new $EVENTS_CLASS(this);\n' | 350 ' if (_on === null) _on = new $EVENTS_CLASS(this);\n' |
| 351 ' return _on;\n' | 351 ' return _on;\n' |
| 352 ' }\n', | 352 ' }\n', |
| 353 EVENTS_CLASS=events_class) | 353 EVENTS_CLASS=events_class) |
| 354 | 354 |
| 355 def _ImplClassName(self, interface_name): | 355 def _ImplClassName(self, interface_name): |
| 356 return '_%sDOMImpl' % interface_name | 356 return '_%sImpl' % interface_name |
| 357 | 357 |
| 358 def _DartType(self, idl_type): | 358 def _DartType(self, idl_type): |
| 359 type_info = GetIDLTypeInfo(idl_type) | 359 type_info = GetIDLTypeInfo(idl_type) |
| 360 return self._HTMLInterfaceName(type_info.dart_type()) | 360 return self._HTMLInterfaceName(type_info.dart_type()) |
| 361 | 361 |
| 362 def _BaseClassName(self): | 362 def _BaseClassName(self): |
| 363 if not self._interface.parents: | 363 if not self._interface.parents: |
| 364 return '_DOMWrapperBase' | 364 return '_DOMWrapperBase' |
| 365 | 365 |
| 366 supertype = self._interface.parents[0].type.id | 366 supertype = self._interface.parents[0].type.id |
| (...skipping 19 matching lines...) Expand all Loading... |
| 386 return self._ImplClassName(supertype) | 386 return self._ImplClassName(supertype) |
| 387 | 387 |
| 388 def _HTMLInterfaceName(self, interface_name): | 388 def _HTMLInterfaceName(self, interface_name): |
| 389 return self._system._html_renames.get(interface_name, interface_name) | 389 return self._system._html_renames.get(interface_name, interface_name) |
| 390 | 390 |
| 391 def _IsConstructable(self): | 391 def _IsConstructable(self): |
| 392 # FIXME: support ConstructorTemplate. | 392 # FIXME: support ConstructorTemplate. |
| 393 return set(['CustomConstructor', 'V8CustomConstructor', 'Constructor', 'Name
dConstructor']) & set(self._interface.ext_attrs) | 393 return set(['CustomConstructor', 'V8CustomConstructor', 'Constructor', 'Name
dConstructor']) & set(self._interface.ext_attrs) |
| 394 | 394 |
| 395 def _EmitFactoryProvider(self, interface_name, constructor_info): | 395 def _EmitFactoryProvider(self, interface_name, constructor_info): |
| 396 implementation_class = '_%sFactoryProviderImpl' % interface_name | |
| 397 implementation_function = 'create' + interface_name | |
| 398 native_implementation_function = '%s_constructor_Callback' % interface_name | |
| 399 | |
| 400 # Emit public implementation in implementation libary. | |
| 401 dart_impl_path = self._system._FilePathForDartFactoryProviderImplementation( | 396 dart_impl_path = self._system._FilePathForDartFactoryProviderImplementation( |
| 402 interface_name) | 397 interface_name) |
| 403 self._system._dom_impl_files.append(dart_impl_path) | 398 self._system._dom_impl_files.append(dart_impl_path) |
| 404 | 399 |
| 405 parameters = constructor_info.ParametersImplementationDeclaration(self._Dart
Type) | 400 html_interface_name = self._HTMLInterfaceName(interface_name) |
| 401 template_file = 'factoryprovider_%s.darttemplate' % html_interface_name |
| 402 template = self._system._templates.TryLoad(template_file) |
| 403 if not template: |
| 404 template = self._system._templates.Load('factoryprovider.darttemplate') |
| 405 |
| 406 native_implementation_function = '%s_constructor_Callback' % interface_name |
| 406 emitter = self._system._emitters.FileEmitter(dart_impl_path) | 407 emitter = self._system._emitters.FileEmitter(dart_impl_path) |
| 407 emitter.Emit( | 408 emitter.Emit( |
| 408 'class $IMPL_CLASS {\n' | 409 template, |
| 409 ' static $TYPE $IMPL_FUNCTION($PARAMETERS)\n' | 410 FACTORYPROVIDER='_%sFactoryProvider' % html_interface_name, |
| 410 ' native "$NATIVE_NAME";\n' | 411 INTERFACE=html_interface_name, |
| 411 '}', | 412 PARAMETERS=constructor_info.ParametersImplementationDeclaration(self._Da
rtType), |
| 412 PARAMETERS=parameters, | 413 ARGUMENTS=constructor_info.ParametersAsArgumentList(), |
| 413 IMPL_CLASS=implementation_class, | |
| 414 TYPE=self._ImplClassName(interface_name), | |
| 415 IMPL_FUNCTION=implementation_function, | |
| 416 NATIVE_NAME=native_implementation_function) | 414 NATIVE_NAME=native_implementation_function) |
| 417 | 415 |
| 418 def FinishInterface(self): | 416 def FinishInterface(self): |
| 417 html_interface_name = self._HTMLInterfaceName(self._interface.id) |
| 418 template = None |
| 419 if html_interface_name == self._interface.id or not self._system._database.H
asInterface(html_interface_name): |
| 420 template_file = 'impl_%s.darttemplate' % html_interface_name |
| 421 template = self._templates.TryLoad(template_file) |
| 422 if not template: |
| 423 template = self._templates.Load('dart_implementation.darttemplate') |
| 424 |
| 419 class_name = self._ImplClassName(self._interface.id) | 425 class_name = self._ImplClassName(self._interface.id) |
| 420 base = self._BaseClassName() | 426 members_emitter = self._dart_impl_emitter.Emit( |
| 421 self._dart_impl_emitter.Emit( | 427 template, |
| 422 self._templates.Load('dart_implementation.darttemplate'), | 428 CLASSNAME=class_name, |
| 423 CLASS=class_name, | 429 EXTENDS=' extends ' + self._BaseClassName(), |
| 424 BASE=base, | 430 IMPLEMENTS=' implements ' + html_interface_name, |
| 425 INTERFACE=self._interface.id, | 431 NATIVESPEC='') |
| 426 HTML_INTERFACE=self._HTMLInterfaceName(self._interface.id), | 432 members_emitter.Emit(''.join(self._members_emitter.Fragments())) |
| 427 MEMBERS=self._members_emitter.Fragments()) | |
| 428 | 433 |
| 429 self._GenerateCppHeader() | 434 self._GenerateCppHeader() |
| 430 | 435 |
| 431 self._cpp_impl_emitter.Emit( | 436 self._cpp_impl_emitter.Emit( |
| 432 self._templates.Load('cpp_implementation.template'), | 437 self._templates.Load('cpp_implementation.template'), |
| 433 INTERFACE=self._interface.id, | 438 INTERFACE=self._interface.id, |
| 434 INCLUDES=_GenerateCPPIncludes(self._cpp_impl_includes), | 439 INCLUDES=_GenerateCPPIncludes(self._cpp_impl_includes), |
| 435 CALLBACKS=self._cpp_definitions_emitter.Fragments(), | 440 CALLBACKS=self._cpp_definitions_emitter.Fragments(), |
| 436 RESOLVER=self._cpp_resolver_emitter.Fragments(), | 441 RESOLVER=self._cpp_resolver_emitter.Fragments(), |
| 437 DART_IMPLEMENTATION_CLASS=class_name) | 442 DART_IMPLEMENTATION_CLASS=class_name) |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 self._members_emitter.Emit( | 648 self._members_emitter.Emit( |
| 644 '\n' | 649 '\n' |
| 645 ' $TYPE operator[](int index) {\n' | 650 ' $TYPE operator[](int index) {\n' |
| 646 ' return item(index);\n' | 651 ' return item(index);\n' |
| 647 ' }\n', | 652 ' }\n', |
| 648 TYPE=dart_element_type) | 653 TYPE=dart_element_type) |
| 649 | 654 |
| 650 if self._HasNativeIndexSetter(): | 655 if self._HasNativeIndexSetter(): |
| 651 self._EmitNativeIndexSetter(dart_element_type) | 656 self._EmitNativeIndexSetter(dart_element_type) |
| 652 else: | 657 else: |
| 653 self._members_emitter.Emit( | 658 # The HTML library implementation of NodeList has a custom indexed setter |
| 654 '\n' | 659 # implementation that uses the parent node the NodeList is associated |
| 655 ' void operator[]=(int index, $TYPE value) {\n' | 660 # with if one is available. |
| 656 ' throw new UnsupportedOperationException("Cannot assign element of
immutable List.");\n' | 661 if self._interface.id != 'NodeList': |
| 657 ' }\n', | 662 self._members_emitter.Emit( |
| 658 TYPE=dart_element_type) | 663 '\n' |
| 664 ' void operator[]=(int index, $TYPE value) {\n' |
| 665 ' throw new UnsupportedOperationException("Cannot assign element
of immutable List.");\n' |
| 666 ' }\n', |
| 667 TYPE=dart_element_type) |
| 659 | 668 |
| 660 self._members_emitter.Emit( | 669 # The list interface for this class is manually generated. |
| 661 '\n' | 670 if self._interface.id == 'NodeList': |
| 662 ' void add($TYPE value) {\n' | 671 return |
| 663 ' throw new UnsupportedOperationException("Cannot add to immutable Li
st.");\n' | 672 |
| 664 ' }\n' | 673 # TODO(sra): Use separate mixins for mutable implementations of List<T>. |
| 665 '\n' | 674 # TODO(sra): Use separate mixins for typed array implementations of List<T>. |
| 666 ' void addLast($TYPE value) {\n' | 675 template_file = 'immutable_list_mixin.darttemplate' |
| 667 ' throw new UnsupportedOperationException("Cannot add to immutable Li
st.");\n' | 676 template = self._system._templates.Load(template_file) |
| 668 ' }\n' | 677 self._members_emitter.Emit(template, E=dart_element_type) |
| 669 '\n' | |
| 670 ' void addAll(Collection<$TYPE> collection) {\n' | |
| 671 ' throw new UnsupportedOperationException("Cannot add to immutable Li
st.");\n' | |
| 672 ' }\n' | |
| 673 '\n' | |
| 674 ' void sort(int compare($TYPE a, $TYPE b)) {\n' | |
| 675 ' throw new UnsupportedOperationException("Cannot sort immutable List
.");\n' | |
| 676 ' }\n' | |
| 677 '\n' | |
| 678 ' void copyFrom(List<Object> src, int srcStart, ' | |
| 679 'int dstStart, int count) {\n' | |
| 680 ' throw new UnsupportedOperationException("This object is immutable."
);\n' | |
| 681 ' }\n' | |
| 682 '\n' | |
| 683 ' int indexOf($TYPE element, [int start = 0]) {\n' | |
| 684 ' return _Lists.indexOf(this, element, start, this.length);\n' | |
| 685 ' }\n' | |
| 686 '\n' | |
| 687 ' int lastIndexOf($TYPE element, [int start = null]) {\n' | |
| 688 ' if (start === null) start = length - 1;\n' | |
| 689 ' return _Lists.lastIndexOf(this, element, start);\n' | |
| 690 ' }\n' | |
| 691 '\n' | |
| 692 ' int clear() {\n' | |
| 693 ' throw new UnsupportedOperationException("Cannot clear immutable Lis
t.");\n' | |
| 694 ' }\n' | |
| 695 '\n' | |
| 696 ' $TYPE removeLast() {\n' | |
| 697 ' throw new UnsupportedOperationException("Cannot removeLast on immut
able List.");\n' | |
| 698 ' }\n' | |
| 699 '\n' | |
| 700 ' $TYPE last() {\n' | |
| 701 ' return this[length - 1];\n' | |
| 702 ' }\n' | |
| 703 '\n' | |
| 704 ' void forEach(void f($TYPE element)) {\n' | |
| 705 ' _Collections.forEach(this, f);\n' | |
| 706 ' }\n' | |
| 707 '\n' | |
| 708 ' Collection map(f($TYPE element)) {\n' | |
| 709 ' return _Collections.map(this, [], f);\n' | |
| 710 ' }\n' | |
| 711 '\n' | |
| 712 ' Collection<$TYPE> filter(bool f($TYPE element)) {\n' | |
| 713 ' return _Collections.filter(this, new List<$TYPE>(), f);\n' | |
| 714 ' }\n' | |
| 715 '\n' | |
| 716 ' bool every(bool f($TYPE element)) {\n' | |
| 717 ' return _Collections.every(this, f);\n' | |
| 718 ' }\n' | |
| 719 '\n' | |
| 720 ' bool some(bool f($TYPE element)) {\n' | |
| 721 ' return _Collections.some(this, f);\n' | |
| 722 ' }\n' | |
| 723 '\n' | |
| 724 ' void setRange(int start, int length, List<$TYPE> from, [int startFrom
]) {\n' | |
| 725 ' throw new UnsupportedOperationException("Cannot setRange on immutab
le List.");\n' | |
| 726 ' }\n' | |
| 727 '\n' | |
| 728 ' void removeRange(int start, int length) {\n' | |
| 729 ' throw new UnsupportedOperationException("Cannot removeRange on immu
table List.");\n' | |
| 730 ' }\n' | |
| 731 '\n' | |
| 732 ' void insertRange(int start, int length, [$TYPE initialValue]) {\n' | |
| 733 ' throw new UnsupportedOperationException("Cannot insertRange on immu
table List.");\n' | |
| 734 ' }\n' | |
| 735 '\n' | |
| 736 ' List<$TYPE> getRange(int start, int length) {\n' | |
| 737 ' throw new NotImplementedException();\n' | |
| 738 ' }\n' | |
| 739 '\n' | |
| 740 ' bool isEmpty() {\n' | |
| 741 ' return length == 0;\n' | |
| 742 ' }\n' | |
| 743 '\n' | |
| 744 ' Iterator<$TYPE> iterator() {\n' | |
| 745 ' return new _FixedSizeListIterator<$TYPE>(this);\n' | |
| 746 ' }\n', | |
| 747 TYPE=dart_element_type) | |
| 748 | 678 |
| 749 def AmendIndexer(self, element_type): | 679 def AmendIndexer(self, element_type): |
| 750 # If interface is marked as having native indexed | 680 # If interface is marked as having native indexed |
| 751 # getter or setter, we must emit overrides as it's not | 681 # getter or setter, we must emit overrides as it's not |
| 752 # guaranteed that the corresponding methods in C++ would be | 682 # guaranteed that the corresponding methods in C++ would be |
| 753 # virtual. For example, as of time of writing, even though | 683 # virtual. For example, as of time of writing, even though |
| 754 # Uint8ClampedArray inherits from Uint8Array, ::set method | 684 # Uint8ClampedArray inherits from Uint8Array, ::set method |
| 755 # is not virtual and accessing it through Uint8Array pointer | 685 # is not virtual and accessing it through Uint8Array pointer |
| 756 # would lead to wrong semantics (modulo vs. clamping.) | 686 # would lead to wrong semantics (modulo vs. clamping.) |
| 757 dart_element_type = self._DartType(element_type) | 687 dart_element_type = self._DartType(element_type) |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 805 self._DartType(info.type_name), | 735 self._DartType(info.type_name), |
| 806 html_name or info.name, | 736 html_name or info.name, |
| 807 info.ParametersImplementationDeclaration(self._DartType)) | 737 info.ParametersImplementationDeclaration(self._DartType)) |
| 808 | 738 |
| 809 if 'Custom' in info.overloads[0].ext_attrs: | 739 if 'Custom' in info.overloads[0].ext_attrs: |
| 810 argument_count = (0 if info.IsStatic() else 1) + len(info.param_infos) | 740 argument_count = (0 if info.IsStatic() else 1) + len(info.param_infos) |
| 811 self._GenerateNativeBinding(info.name , argument_count, | 741 self._GenerateNativeBinding(info.name , argument_count, |
| 812 dart_declaration, 'Callback', True) | 742 dart_declaration, 'Callback', True) |
| 813 return | 743 return |
| 814 | 744 |
| 815 body = self._members_emitter.Emit( | 745 if self._interface.id == 'Document' and info.name == 'querySelector': |
| 816 '\n' | 746 # Document.querySelector has custom implementation in dart:html. |
| 817 ' $DECLARATION {\n' | 747 # FIXME: Cleanup query selectors and remove this hack. |
| 818 '$!BODY' | 748 body = emitter.Emitter() |
| 819 ' }\n', | 749 else: |
| 820 DECLARATION=dart_declaration) | 750 body = self._members_emitter.Emit( |
| 751 '\n' |
| 752 ' $DECLARATION {\n' |
| 753 '$!BODY' |
| 754 ' }\n', |
| 755 DECLARATION=dart_declaration) |
| 821 | 756 |
| 822 self._native_version = 0 | 757 self._native_version = 0 |
| 823 overloads = self.CombineOverloads(info.overloads) | 758 overloads = self.CombineOverloads(info.overloads) |
| 824 fallthrough = self.GenerateDispatch(body, info, ' ', overloads) | 759 fallthrough = self.GenerateDispatch(body, info, ' ', overloads) |
| 825 if fallthrough: | 760 if fallthrough: |
| 826 body.Emit(' throw "Incorrect number or type of arguments";\n'); | 761 body.Emit(' throw "Incorrect number or type of arguments";\n'); |
| 827 | 762 |
| 828 def CombineOverloads(self, overloads): | 763 def CombineOverloads(self, overloads): |
| 829 # Combine overloads that can be implemented by the same native method. This | 764 # Combine overloads that can be implemented by the same native method. This |
| 830 # undoes the expansion of optional arguments into multiple overloads unless | 765 # undoes the expansion of optional arguments into multiple overloads unless |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1206 ' }\n', | 1141 ' }\n', |
| 1207 INVOCATION=invocation_template) | 1142 INVOCATION=invocation_template) |
| 1208 | 1143 |
| 1209 if 'ImplementedBy' in attributes: | 1144 if 'ImplementedBy' in attributes: |
| 1210 arguments.insert(0, 'receiver') | 1145 arguments.insert(0, 'receiver') |
| 1211 self._cpp_impl_includes.add('"%s.h"' % attributes['ImplementedBy']) | 1146 self._cpp_impl_includes.add('"%s.h"' % attributes['ImplementedBy']) |
| 1212 | 1147 |
| 1213 return emitter.Format(invocation_template, | 1148 return emitter.Format(invocation_template, |
| 1214 FUNCTION_CALL='%s(%s)' % (function_expression, ', '.join(arguments))) | 1149 FUNCTION_CALL='%s(%s)' % (function_expression, ', '.join(arguments))) |
| 1215 | 1150 |
| 1151 |
| 1216 def _GenerateCPPIncludes(includes): | 1152 def _GenerateCPPIncludes(includes): |
| 1217 return ''.join(['#include %s\n' % include for include in includes]) | 1153 return ''.join(['#include %s\n' % include for include in includes]) |
| 1218 | 1154 |
| 1219 def _DOMWrapperType(database, interface): | 1155 def _DOMWrapperType(database, interface): |
| 1220 if interface.id == 'MessagePort': | 1156 if interface.id == 'MessagePort': |
| 1221 return 'MessagePort' | 1157 return 'MessagePort' |
| 1222 | 1158 |
| 1223 type = 'Object' | 1159 type = 'Object' |
| 1224 def is_node(interface): | 1160 def is_node(interface): |
| 1225 return interface.id == 'Node' | 1161 return interface.id == 'Node' |
| 1226 if is_node(interface) or _FindParent(interface, database, is_node): | 1162 if is_node(interface) or _FindParent(interface, database, is_node): |
| 1227 type = 'Node' | 1163 type = 'Node' |
| 1228 if 'ActiveDOMObject' in interface.ext_attrs: | 1164 if 'ActiveDOMObject' in interface.ext_attrs: |
| 1229 type = 'Active%s' % type | 1165 type = 'Active%s' % type |
| 1230 return type | 1166 return type |
| 1231 | 1167 |
| 1232 def _FindParent(interface, database, callback): | 1168 def _FindParent(interface, database, callback): |
| 1233 for parent in interface.parents: | 1169 for parent in interface.parents: |
| 1234 parent_name = parent.type.id | 1170 parent_name = parent.type.id |
| 1235 if not database.HasInterface(parent.type.id): | 1171 if not database.HasInterface(parent.type.id): |
| 1236 continue | 1172 continue |
| 1237 parent_interface = database.GetInterface(parent.type.id) | 1173 parent_interface = database.GetInterface(parent.type.id) |
| 1238 if callback(parent_interface): | 1174 if callback(parent_interface): |
| 1239 return parent_interface | 1175 return parent_interface |
| 1240 parent_interface = _FindParent(parent_interface, database, callback) | 1176 parent_interface = _FindParent(parent_interface, database, callback) |
| 1241 if parent_interface: | 1177 if parent_interface: |
| 1242 return parent_interface | 1178 return parent_interface |
| OLD | NEW |