| 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 import logging | 10 import logging |
| (...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 self._interface) | 487 self._interface) |
| 488 | 488 |
| 489 code.Emit('$(ANNOTATIONS)typedef void $NAME($PARAMS);\n', | 489 code.Emit('$(ANNOTATIONS)typedef void $NAME($PARAMS);\n', |
| 490 ANNOTATIONS=annotations, | 490 ANNOTATIONS=annotations, |
| 491 NAME=typedef_name, | 491 NAME=typedef_name, |
| 492 PARAMS=info.ParametersAsDeclaration(self._DartType)) | 492 PARAMS=info.ParametersAsDeclaration(self._DartType)) |
| 493 self._backend.GenerateCallback(info) | 493 self._backend.GenerateCallback(info) |
| 494 | 494 |
| 495 def GenerateInterface(self): | 495 def GenerateInterface(self): |
| 496 interface_name = self._interface_type_info.interface_name() | 496 interface_name = self._interface_type_info.interface_name() |
| 497 |
| 497 implementation_name = self._interface_type_info.implementation_name() | 498 implementation_name = self._interface_type_info.implementation_name() |
| 498 self._library_emitter.AddTypeEntry(self._library_name, | 499 self._library_emitter.AddTypeEntry(self._library_name, |
| 499 self._interface.id, implementation_name) | 500 self._interface.id, implementation_name) |
| 500 | 501 |
| 501 factory_provider = None | 502 factory_provider = None |
| 502 if interface_name in interface_factories: | 503 if interface_name in interface_factories: |
| 503 factory_provider = interface_factories[interface_name] | 504 factory_provider = interface_factories[interface_name] |
| 504 factory_constructor_name = None | 505 factory_constructor_name = None |
| 505 | 506 |
| 506 constructors = [] | 507 constructors = [] |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 secure_base_name = self._backend.SecureBaseName(interface_name) | 553 secure_base_name = self._backend.SecureBaseName(interface_name) |
| 553 if secure_base_name: | 554 if secure_base_name: |
| 554 implements.append(secure_base_name) | 555 implements.append(secure_base_name) |
| 555 | 556 |
| 556 implements_str = '' | 557 implements_str = '' |
| 557 if implements: | 558 if implements: |
| 558 implements_str = ' implements ' + ', '.join(set(implements)) | 559 implements_str = ' implements ' + ', '.join(set(implements)) |
| 559 | 560 |
| 560 mixins = self._backend.Mixins() | 561 mixins = self._backend.Mixins() |
| 561 | 562 |
| 562 # TODO(terry): Do we need a more generic solution other than handling NamedN
odeMap | |
| 563 # we can't call super on a mixin interface - yet. | |
| 564 if self._options.templates._conditions['DARTIUM'] and self._options.dart_js_
interop and self._interface.id == 'NamedNodeMap': | |
| 565 mixins = None | |
| 566 mixins_str = '' | 563 mixins_str = '' |
| 567 if mixins: | 564 if mixins: |
| 568 mixins_str = ' with ' + ', '.join(mixins) | 565 mixins_str = ' with ' + ', '.join(mixins) |
| 569 if not base_class: | 566 if not base_class: |
| 570 base_class = 'Interceptor' | 567 base_class = 'Interceptor' |
| 568 elif (base_class == 'NativeFieldWrapperClass2' and |
| 569 self._options.dart_js_interop and |
| 570 not(isinstance(self._backend, Dart2JSBackend))): |
| 571 base_class = 'JsoNativeFieldWrapper' |
| 571 | 572 |
| 572 annotations = self._metadata.GetFormattedMetadata( | 573 annotations = self._metadata.GetFormattedMetadata( |
| 573 self._library_name, self._interface, None, '') | 574 self._library_name, self._interface, None, '') |
| 574 | 575 |
| 575 class_modifiers = '' | 576 class_modifiers = '' |
| 576 if (self._renamer.ShouldSuppressInterface(self._interface) or | 577 if (self._renamer.ShouldSuppressInterface(self._interface) or |
| 577 IsPureInterface(self._interface.id)): | 578 IsPureInterface(self._interface.id)): |
| 578 # XMLHttpRequestProgressEvent can't be abstract we need to instantiate | 579 # XMLHttpRequestProgressEvent can't be abstract we need to instantiate |
| 579 # for JsInterop. | 580 # for JsInterop. |
| 580 if (not(isinstance(self._backend, Dart2JSBackend)) and | 581 if (not(isinstance(self._backend, Dart2JSBackend)) and |
| 581 self._interface.id == 'XMLHttpRequestProgressEvent'): | 582 self._interface.id == 'XMLHttpRequestProgressEvent'): |
| 582 # Only suppress abstract for XMLHttpRequestProgressEvent for Dartium. | 583 # Only suppress abstract for XMLHttpRequestProgressEvent for Dartium. |
| 583 # Need to be able to instantiate the class; can't be abstract. | 584 # Need to be able to instantiate the class; can't be abstract. |
| 584 class_modifiers = '' | 585 class_modifiers = '' |
| 585 else: | 586 else: |
| 586 class_modifiers = 'abstract ' | 587 # For Dartium w/ JsInterop these suppressed interfaces are needed to |
| 588 # instanciate the internal classes when wrap_jso is called for a JS obje
ct. |
| 589 if (self._renamer.ShouldSuppressInterface(self._interface) and |
| 590 not(isinstance(self._backend, Dart2JSBackend)) and |
| 591 self._options.dart_js_interop): |
| 592 class_modifiers = '' |
| 593 else: |
| 594 class_modifiers = 'abstract ' |
| 587 | 595 |
| 588 native_spec = '' | 596 native_spec = '' |
| 589 if not IsPureInterface(self._interface.id): | 597 if not IsPureInterface(self._interface.id): |
| 590 native_spec = self._backend.NativeSpec() | 598 native_spec = self._backend.NativeSpec() |
| 591 | 599 |
| 592 class_name = self._interface_type_info.implementation_name() | 600 class_name = self._interface_type_info.implementation_name() |
| 593 | 601 |
| 594 js_interop_equivalence_op = \ | 602 js_interop_equivalence_op = \ |
| 595 ' bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || ide
ntical(this, other);\n' | 603 ' bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || ide
ntical(this, other);\n' \ |
| 604 + ' int get hashCode => unwrap_jso(this).hashCode;\n' |
| 596 # ClientRect overrides the equivalence operator. | 605 # ClientRect overrides the equivalence operator. |
| 597 if interface_name == 'ClientRect' or interface_name == 'DomRectReadOnly': | 606 if interface_name == 'ClientRect' or interface_name == 'DomRectReadOnly': |
| 598 js_interop_equivalence_op = '' | 607 js_interop_equivalence_op = '' |
| 599 | 608 |
| 600 js_interop_wrapper = ''' | 609 js_interop_wrapper = ''' |
| 601 | 610 |
| 602 static {0} internalCreate{0}() {{ | 611 static {0} internalCreate{0}() {{ |
| 603 return new {0}._internalWrap(); | 612 return new {0}._internalWrap(); |
| 604 }} | 613 }} |
| 605 | 614 |
| 606 factory {0}._internalWrap() {{ | 615 factory {0}._internalWrap() {{ |
| 607 return new {0}._internal(); | 616 return new {0}.internal_(); |
| 608 }} | 617 }} |
| 609 | 618 |
| 610 {0}._internal() : super._internal(); | 619 {0}.internal_() : super.internal_(); |
| 611 | 620 |
| 612 '''.format(class_name) | 621 '''.format(class_name) |
| 613 """ | 622 """ |
| 614 TODO(terry): Don't use Dart expando really don't need. | 623 TODO(terry): Don't use Dart expando really don't need. |
| 615 final Object expandoJsObject = new Object(); | 624 final Object expandoJsObject = new Object(); |
| 616 final Expando<JsObject> dartium_expando = new Expando<JsObject>("Expando_j
sObject"); | 625 final Expando<JsObject> dartium_expando = new Expando<JsObject>("Expando_j
sObject"); |
| 617 """ | 626 """ |
| 618 if base_class == 'NativeFieldWrapperClass2': | 627 if base_class == 'NativeFieldWrapperClass2' or base_class == 'JsoNativeField
Wrapper': |
| 619 js_interop_wrapper = ''' | 628 js_interop_wrapper = ''' |
| 620 static {0} internalCreate{0}() {{ | 629 static {0} internalCreate{0}() {{ |
| 621 return new {0}._internalWrap(); | 630 return new {0}._internalWrap(); |
| 622 }} | 631 }} |
| 623 | 632 |
| 624 JsObject blink_jsObject = null; | 633 js.JsObject blink_jsObject; |
| 625 | 634 |
| 626 factory {0}._internalWrap() {{ | 635 factory {0}._internalWrap() {{ |
| 627 return new {0}._internal(); | 636 return new {0}.internal_(); |
| 628 }} | 637 }} |
| 629 | 638 |
| 630 {0}._internal() {{ }} | 639 {0}.internal_() {{ }} |
| 631 | 640 |
| 632 {1}'''.format(class_name, js_interop_equivalence_op) | 641 {1}'''.format(class_name, js_interop_equivalence_op) |
| 642 # Change to use the synthesized class so we can construct with a mixin |
| 643 # classes prefixed with name of NativeFieldWrapperClass2 don't have a |
| 644 # default constructor so classes with mixins can't be new'd. |
| 645 if (self._options.templates._conditions['DARTIUM'] and |
| 646 self._options.dart_js_interop and |
| 647 (self._interface.id == 'NamedNodeMap' or |
| 648 self._interface.id == 'CSSStyleDeclaration')): |
| 649 base_class = 'JsoNativeFieldWrapper' |
| 633 | 650 |
| 634 implementation_members_emitter = implementation_emitter.Emit( | 651 implementation_members_emitter = implementation_emitter.Emit( |
| 635 self._backend.ImplementationTemplate(), | 652 self._backend.ImplementationTemplate(), |
| 636 LIBRARYNAME='dart.dom.%s' % self._library_name, | 653 LIBRARYNAME='dart.dom.%s' % self._library_name, |
| 637 ANNOTATIONS=annotations, | 654 ANNOTATIONS=annotations, |
| 638 CLASS_MODIFIERS=class_modifiers, | 655 CLASS_MODIFIERS=class_modifiers, |
| 639 CLASSNAME=self._interface_type_info.implementation_name(), | 656 CLASSNAME=self._interface_type_info.implementation_name(), |
| 640 EXTENDS=' extends %s' % base_class if base_class else '', | 657 EXTENDS=' extends %s' % base_class if base_class else '', |
| 641 IMPLEMENTS=implements_str, | 658 IMPLEMENTS=implements_str, |
| 642 MIXINS=mixins_str, | 659 MIXINS=mixins_str, |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 973 TYPE=return_type, | 990 TYPE=return_type, |
| 974 NATIVE_TYPE=native_type) | 991 NATIVE_TYPE=native_type) |
| 975 | 992 |
| 976 def _AddRenamingSetter(self, attr, html_name): | 993 def _AddRenamingSetter(self, attr, html_name): |
| 977 | 994 |
| 978 conversion = self._InputConversion(attr.type.id, attr.id) | 995 conversion = self._InputConversion(attr.type.id, attr.id) |
| 979 if conversion: | 996 if conversion: |
| 980 return self._AddConvertingSetter(attr, html_name, conversion) | 997 return self._AddConvertingSetter(attr, html_name, conversion) |
| 981 self._members_emitter.Emit( | 998 self._members_emitter.Emit( |
| 982 # TODO(sra): Use metadata to provide native name. | 999 # TODO(sra): Use metadata to provide native name. |
| 983 '\n void set $HTML_NAME($TYPE value) {' | 1000 '\n set $HTML_NAME($TYPE value) {' |
| 984 '\n JS("void", "#.$NAME = #", this, value);' | 1001 '\n JS("void", "#.$NAME = #", this, value);' |
| 985 '\n }' | 1002 '\n }' |
| 986 '\n', | 1003 '\n', |
| 987 HTML_NAME=html_name, | 1004 HTML_NAME=html_name, |
| 988 NAME=attr.id, | 1005 NAME=attr.id, |
| 989 TYPE=self._NarrowInputType(attr.type.id)) | 1006 TYPE=self._NarrowInputType(attr.type.id)) |
| 990 | 1007 |
| 991 def _AddConvertingGetter(self, attr, html_name, conversion): | 1008 def _AddConvertingGetter(self, attr, html_name, conversion): |
| 992 self._members_emitter.Emit( | 1009 self._members_emitter.Emit( |
| 993 '\n $(METADATA)$RETURN_TYPE get $HTML_NAME => ' | 1010 '\n $(METADATA)$RETURN_TYPE get $HTML_NAME => ' |
| 994 '$CONVERT(this._get_$(HTML_NAME));' | 1011 '$CONVERT(this._get_$(HTML_NAME));' |
| 995 "\n @JSName('$NAME')" | 1012 "\n @JSName('$NAME')" |
| 996 '\n $(JS_METADATA)final $NATIVE_TYPE _get_$HTML_NAME;' | 1013 '\n $(JS_METADATA)final $NATIVE_TYPE _get_$HTML_NAME;' |
| 997 '\n', | 1014 '\n', |
| 998 METADATA=self._metadata.GetFormattedMetadata( | 1015 METADATA=self._metadata.GetFormattedMetadata( |
| 999 self._library_name, self._interface, html_name, ' '), | 1016 self._library_name, self._interface, html_name, ' '), |
| 1000 JS_METADATA=self._Metadata(attr.type.id, html_name, conversion.input_typ
e), | 1017 JS_METADATA=self._Metadata(attr.type.id, html_name, conversion.input_typ
e), |
| 1001 CONVERT=conversion.function_name, | 1018 CONVERT=conversion.function_name, |
| 1002 HTML_NAME=html_name, | 1019 HTML_NAME=html_name, |
| 1003 NAME=attr.id, | 1020 NAME=attr.id, |
| 1004 RETURN_TYPE=conversion.output_type, | 1021 RETURN_TYPE=conversion.output_type, |
| 1005 NATIVE_TYPE=conversion.input_type) | 1022 NATIVE_TYPE=conversion.input_type) |
| 1006 | 1023 |
| 1007 def _AddConvertingSetter(self, attr, html_name, conversion): | 1024 def _AddConvertingSetter(self, attr, html_name, conversion): |
| 1008 self._members_emitter.Emit( | 1025 self._members_emitter.Emit( |
| 1009 # TODO(sra): Use metadata to provide native name. | 1026 # TODO(sra): Use metadata to provide native name. |
| 1010 '\n void set $HTML_NAME($INPUT_TYPE value) {' | 1027 '\n set $HTML_NAME($INPUT_TYPE value) {' |
| 1011 '\n this._set_$HTML_NAME = $CONVERT(value);' | 1028 '\n this._set_$HTML_NAME = $CONVERT(value);' |
| 1012 '\n }' | 1029 '\n }' |
| 1013 '\n void set _set_$HTML_NAME(/*$NATIVE_TYPE*/ value) {' | 1030 '\n set _set_$HTML_NAME(/*$NATIVE_TYPE*/ value) {' |
| 1014 '\n JS("void", "#.$NAME = #", this, value);' | 1031 '\n JS("void", "#.$NAME = #", this, value);' |
| 1015 '\n }' | 1032 '\n }' |
| 1016 '\n', | 1033 '\n', |
| 1017 CONVERT=conversion.function_name, | 1034 CONVERT=conversion.function_name, |
| 1018 HTML_NAME=html_name, | 1035 HTML_NAME=html_name, |
| 1019 NAME=attr.id, | 1036 NAME=attr.id, |
| 1020 INPUT_TYPE=conversion.input_type, | 1037 INPUT_TYPE=conversion.input_type, |
| 1021 NATIVE_TYPE=conversion.output_type) | 1038 NATIVE_TYPE=conversion.output_type) |
| 1022 | 1039 |
| 1023 def AmendIndexer(self, element_type): | 1040 def AmendIndexer(self, element_type): |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1052 '\n' | 1069 '\n' |
| 1053 ' $RENAME$METADATA$MODIFIERS$TYPE $NAME($PARAMS) native;\n', | 1070 ' $RENAME$METADATA$MODIFIERS$TYPE $NAME($PARAMS) native;\n', |
| 1054 RENAME=self._RenamingAnnotation(info.declared_name, html_name), | 1071 RENAME=self._RenamingAnnotation(info.declared_name, html_name), |
| 1055 METADATA=self._Metadata(info.type_name, info.declared_name, | 1072 METADATA=self._Metadata(info.type_name, info.declared_name, |
| 1056 self.SecureOutputType(info.type_name)), | 1073 self.SecureOutputType(info.type_name)), |
| 1057 MODIFIERS='static ' if info.IsStatic() else '', | 1074 MODIFIERS='static ' if info.IsStatic() else '', |
| 1058 TYPE=self.SecureOutputType(info.type_name, False, True), | 1075 TYPE=self.SecureOutputType(info.type_name, False, True), |
| 1059 NAME=html_name, | 1076 NAME=html_name, |
| 1060 PARAMS=info.ParametersAsDeclaration(self._NarrowInputType)) | 1077 PARAMS=info.ParametersAsDeclaration(self._NarrowInputType)) |
| 1061 | 1078 |
| 1062 def _ConvertArgumentTypes( | |
| 1063 self, stmts_emitter, arguments, argument_count, info): | |
| 1064 temp_version = [0] | |
| 1065 converted_arguments = [] | |
| 1066 target_parameters = [] | |
| 1067 for position, arg in enumerate(arguments[:argument_count]): | |
| 1068 conversion = self._InputConversion(arg.type.id, info.declared_name) | |
| 1069 param_name = arguments[position].id | |
| 1070 if conversion: | |
| 1071 temp_version[0] += 1 | |
| 1072 temp_name = '%s_%s' % (param_name, temp_version[0]) | |
| 1073 temp_type = conversion.output_type | |
| 1074 stmts_emitter.Emit( | |
| 1075 '$(INDENT)$TYPE $NAME = $CONVERT($ARG);\n', | |
| 1076 TYPE=TypeOrVar(temp_type), | |
| 1077 NAME=temp_name, | |
| 1078 CONVERT=conversion.function_name, | |
| 1079 ARG=info.param_infos[position].name) | |
| 1080 converted_arguments.append(temp_name) | |
| 1081 param_type = temp_type | |
| 1082 verified_type = temp_type # verified by assignment in checked mode. | |
| 1083 else: | |
| 1084 converted_arguments.append(info.param_infos[position].name) | |
| 1085 param_type = self._NarrowInputType(arg.type.id) | |
| 1086 # Verified by argument checking on entry to the dispatcher. | |
| 1087 | |
| 1088 verified_type = self._InputType( | |
| 1089 info.param_infos[position].type_id, info) | |
| 1090 # The native method does not need an argument type if we know the type. | |
| 1091 # But we do need the native methods to have correct function types, so | |
| 1092 # be conservative. | |
| 1093 if param_type == verified_type: | |
| 1094 if param_type in ['String', 'num', 'int', 'double', 'bool', 'Object']: | |
| 1095 param_type = 'dynamic' | |
| 1096 | |
| 1097 target_parameters.append( | |
| 1098 '%s%s' % (TypeOrNothing(param_type), param_name)) | |
| 1099 | |
| 1100 return target_parameters, converted_arguments | |
| 1101 | |
| 1102 def _InputType(self, type_name, info): | |
| 1103 conversion = self._InputConversion(type_name, info.declared_name) | |
| 1104 if conversion: | |
| 1105 return conversion.input_type | |
| 1106 else: | |
| 1107 return self._NarrowInputType(type_name) if type_name else 'dynamic' | |
| 1108 | |
| 1109 def _AddOperationWithConversions(self, info, html_name): | 1079 def _AddOperationWithConversions(self, info, html_name): |
| 1110 # Assert all operations have same return type. | 1080 # Assert all operations have same return type. |
| 1111 assert len(set([op.type.id for op in info.operations])) == 1 | 1081 assert len(set([op.type.id for op in info.operations])) == 1 |
| 1112 output_conversion = self._OutputConversion(info.type_name, | 1082 output_conversion = self._OutputConversion(info.type_name, |
| 1113 info.declared_name) | 1083 info.declared_name) |
| 1114 if output_conversion: | 1084 if output_conversion: |
| 1115 return_type = output_conversion.output_type | 1085 return_type = output_conversion.output_type |
| 1116 native_return_type = output_conversion.input_type | 1086 native_return_type = output_conversion.input_type |
| 1117 else: | 1087 else: |
| 1118 return_type = self._NarrowInputType(info.type_name) | 1088 return_type = self._NarrowInputType(info.type_name) |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1365 | 1335 |
| 1366 def AddFile(self, basename, library_name, path): | 1336 def AddFile(self, basename, library_name, path): |
| 1367 self._libraries[library_name].AddFile(path) | 1337 self._libraries[library_name].AddFile(path) |
| 1368 | 1338 |
| 1369 def AddTypeEntry(self, library_name, idl_name, dart_name): | 1339 def AddTypeEntry(self, library_name, idl_name, dart_name): |
| 1370 self._libraries[library_name].AddTypeEntry(idl_name, dart_name) | 1340 self._libraries[library_name].AddTypeEntry(idl_name, dart_name) |
| 1371 | 1341 |
| 1372 def Emit(self, emitter, auxiliary_dir): | 1342 def Emit(self, emitter, auxiliary_dir): |
| 1373 for lib in self._libraries.values(): | 1343 for lib in self._libraries.values(): |
| 1374 lib.Emit(emitter, auxiliary_dir) | 1344 lib.Emit(emitter, auxiliary_dir) |
| OLD | NEW |