| 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 os | 10 import os |
| 11 from generator import * | 11 from generator import * |
| 12 from htmldartgenerator import * |
| 12 | 13 |
| 13 _js_custom_members = set([ | 14 _js_custom_members = set([ |
| 14 'AudioBufferSourceNode.start', | 15 'AudioBufferSourceNode.start', |
| 15 'AudioBufferSourceNode.stop', | 16 'AudioBufferSourceNode.stop', |
| 16 'CSSStyleDeclaration.setProperty', | 17 'CSSStyleDeclaration.setProperty', |
| 17 'Element.insertAdjacentElement', | 18 'Element.insertAdjacentElement', |
| 18 'Element.insertAdjacentHTML', | 19 'Element.insertAdjacentHTML', |
| 19 'Element.insertAdjacentText', | 20 'Element.insertAdjacentText', |
| 20 'Element.remove', | 21 'Element.remove', |
| 21 'ElementEvents.mouseWheel', | 22 'ElementEvents.mouseWheel', |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 return infos | 174 return infos |
| 174 | 175 |
| 175 def EmitHtmlElementFactoryConstructors(emitter, infos, typename, class_name, | 176 def EmitHtmlElementFactoryConstructors(emitter, infos, typename, class_name, |
| 176 rename_type): | 177 rename_type): |
| 177 for info in infos: | 178 for info in infos: |
| 178 constructor_info = info.ConstructorInfo(typename) | 179 constructor_info = info.ConstructorInfo(typename) |
| 179 | 180 |
| 180 inits = emitter.Emit( | 181 inits = emitter.Emit( |
| 181 '\n' | 182 '\n' |
| 182 ' static $RETURN_TYPE $CONSTRUCTOR($PARAMS) {\n' | 183 ' static $RETURN_TYPE $CONSTRUCTOR($PARAMS) {\n' |
| 183 ' $CLASS _e = _document.$dom_createElement("$TAG");\n' | 184 ' $CLASS _e = document.$dom_createElement("$TAG");\n' |
| 184 '$!INITS' | 185 '$!INITS' |
| 185 ' return _e;\n' | 186 ' return _e;\n' |
| 186 ' }\n', | 187 ' }\n', |
| 187 RETURN_TYPE=rename_type(constructor_info.type_name), | 188 RETURN_TYPE=rename_type(constructor_info.type_name), |
| 188 CONSTRUCTOR=constructor_info.ConstructorFactoryName(rename_type), | 189 CONSTRUCTOR=constructor_info.ConstructorFactoryName(rename_type), |
| 189 CLASS=class_name, | 190 CLASS=class_name, |
| 190 TAG=info.tag, | 191 TAG=info.tag, |
| 191 PARAMS=constructor_info.ParametersDeclaration( | 192 PARAMS=constructor_info.ParametersDeclaration( |
| 192 rename_type, force_optional=True)) | 193 rename_type, force_optional=True)) |
| 193 for param in constructor_info.param_infos: | 194 for param in constructor_info.param_infos: |
| (...skipping 30 matching lines...) Expand all Loading... |
| 224 code = self._library_emitter.FileEmitter(self._interface.id) | 225 code = self._library_emitter.FileEmitter(self._interface.id) |
| 225 code.Emit(self._template_loader.Load('callback.darttemplate')) | 226 code.Emit(self._template_loader.Load('callback.darttemplate')) |
| 226 code.Emit('typedef void $NAME($PARAMS);\n', | 227 code.Emit('typedef void $NAME($PARAMS);\n', |
| 227 NAME=self._interface.id, | 228 NAME=self._interface.id, |
| 228 PARAMS=info.ParametersDeclaration(self._DartType)) | 229 PARAMS=info.ParametersDeclaration(self._DartType)) |
| 229 self._backend.GenerateCallback(info) | 230 self._backend.GenerateCallback(info) |
| 230 | 231 |
| 231 def GenerateInterface(self): | 232 def GenerateInterface(self): |
| 232 interface_name = self._interface_type_info.interface_name() | 233 interface_name = self._interface_type_info.interface_name() |
| 233 | 234 |
| 234 if (self._interface_type_info.has_generated_interface() and | 235 # TODO: this is just tossing the interface, need to skip it completely. |
| 235 not self._interface_type_info.merged_into()): | 236 interface_emitter = emitter.Emitter() |
| 236 interface_emitter = self._library_emitter.FileEmitter(interface_name) | |
| 237 else: | |
| 238 interface_emitter = emitter.Emitter() | |
| 239 | 237 |
| 240 template_file = 'interface_%s.darttemplate' % interface_name | 238 template_file = 'interface_%s.darttemplate' % interface_name |
| 241 interface_template = (self._template_loader.TryLoad(template_file) or | 239 interface_template = (self._template_loader.TryLoad(template_file) or |
| 242 self._template_loader.Load('interface.darttemplate')) | 240 self._template_loader.Load('interface.darttemplate')) |
| 243 | 241 |
| 244 implements = [] | 242 implements = [] |
| 245 for parent in self._interface.parents: | 243 for parent in self._interface.parents: |
| 246 parent_type_info = self._type_registry.TypeInfo(parent.type.id) | 244 parent_type_info = self._type_registry.TypeInfo(parent.type.id) |
| 247 implements.append(parent_type_info.interface_name()) | 245 implements.append(parent_type_info.interface_name()) |
| 248 | 246 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 if factory_provider: | 288 if factory_provider: |
| 291 assert factory_provider == info.factory_provider_name | 289 assert factory_provider == info.factory_provider_name |
| 292 else: | 290 else: |
| 293 factory_provider = info.factory_provider_name | 291 factory_provider = info.factory_provider_name |
| 294 | 292 |
| 295 # TODO(vsm): Add appropriate package / namespace syntax. | 293 # TODO(vsm): Add appropriate package / namespace syntax. |
| 296 (self._type_comment_emitter, | 294 (self._type_comment_emitter, |
| 297 self._members_emitter, | 295 self._members_emitter, |
| 298 self._top_level_emitter) = interface_emitter.Emit( | 296 self._top_level_emitter) = interface_emitter.Emit( |
| 299 interface_template + '$!TOP_LEVEL', | 297 interface_template + '$!TOP_LEVEL', |
| 300 ID=interface_name, | 298 ID='_I%s' % interface_name, |
| 301 EXTENDS=implements_str) | 299 EXTENDS=implements_str) |
| 302 | 300 |
| 303 self._type_comment_emitter.Emit("/// @domName $DOMNAME", | |
| 304 DOMNAME=self._interface.doc_js_name) | |
| 305 | |
| 306 implementation_emitter = self._ImplementationEmitter() | 301 implementation_emitter = self._ImplementationEmitter() |
| 307 | 302 |
| 308 base_class = self._backend.RootClassName() | 303 base_class = self._backend.RootClassName() |
| 304 base_type_info = None |
| 305 |
| 309 if self._interface.parents: | 306 if self._interface.parents: |
| 310 supertype = self._interface.parents[0].type.id | 307 supertype = self._interface.parents[0].type.id |
| 311 if not IsDartCollectionType(supertype) and not IsPureInterface(supertype): | 308 if not IsDartCollectionType(supertype) and not IsPureInterface(supertype): |
| 312 type_info = self._type_registry.TypeInfo(supertype) | 309 base_type_info = self._type_registry.TypeInfo(supertype) |
| 313 if type_info.merged_into() and self._backend.ImplementsMergedMembers(): | 310 if base_type_info.merged_into() \ |
| 314 type_info = self._type_registry.TypeInfo(type_info.merged_into()) | 311 and self._backend.ImplementsMergedMembers(): |
| 315 base_class = type_info.implementation_name() | 312 base_type_info = self._type_registry.TypeInfo( |
| 313 base_type_info.merged_into()) |
| 314 base_class = base_type_info.implementation_name() |
| 316 | 315 |
| 317 implemented_interfaces = [interface_name] +\ | 316 implements = self._backend.AdditionalImplementedInterfaces() |
| 318 self._backend.AdditionalImplementedInterfaces() | 317 |
| 318 for parent in self._interface.parents: |
| 319 parent_type_info = self._type_registry.TypeInfo(parent.type.id) |
| 320 if parent_type_info != base_type_info: |
| 321 implements.append(parent_type_info.interface_name()) |
| 322 |
| 323 if interface_name in _secure_base_types: |
| 324 implements.append(_secure_base_types[interface_name]) |
| 325 |
| 326 implements_str = '' |
| 327 if implements: |
| 328 implements_str += ' implements ' + ', '.join(set(implements)) |
| 329 |
| 319 self._implementation_members_emitter = implementation_emitter.Emit( | 330 self._implementation_members_emitter = implementation_emitter.Emit( |
| 320 self._backend.ImplementationTemplate(), | 331 self._backend.ImplementationTemplate(), |
| 321 CLASSNAME=self._interface_type_info.implementation_name(), | 332 CLASSNAME=self._interface_type_info.implementation_name(), |
| 322 EXTENDS=' extends %s' % base_class if base_class else '', | 333 EXTENDS=' extends %s' % base_class if base_class else '', |
| 323 IMPLEMENTS=' implements ' + ', '.join(implemented_interfaces), | 334 IMPLEMENTS=implements_str, |
| 335 DOMNAME=self._interface.doc_js_name, |
| 324 NATIVESPEC=self._backend.NativeSpec()) | 336 NATIVESPEC=self._backend.NativeSpec()) |
| 325 self._backend.StartInterface(self._implementation_members_emitter) | 337 self._backend.StartInterface(self._implementation_members_emitter) |
| 326 | 338 |
| 327 for constructor_info in constructors: | 339 for constructor_info in constructors: |
| 328 constructor_info.GenerateFactoryInvocation( | 340 constructor_info.GenerateFactoryInvocation( |
| 329 self._DartType, self._members_emitter, factory_provider) | 341 self._DartType, self._members_emitter, factory_provider) |
| 330 | 342 |
| 331 element_type = None | 343 self._backend.AddConstructors(constructors, factory_provider, |
| 344 self._interface_type_info.implementation_name(), |
| 345 base_class) |
| 346 |
| 347 typed_array_type = None |
| 332 for interface in self._database.Hierarchy(self._interface): | 348 for interface in self._database.Hierarchy(self._interface): |
| 333 type_info = self._type_registry.TypeInfo(interface.id) | 349 type_info = self._type_registry.TypeInfo(interface.id) |
| 334 if type_info.is_typed_array(): | 350 if type_info.is_typed_array(): |
| 335 element_type = type_info.list_item_type() | 351 typed_array_type = type_info.list_item_type() |
| 336 break | 352 break |
| 337 if element_type: | 353 if typed_array_type: |
| 338 self._members_emitter.Emit( | 354 self._members_emitter.Emit( |
| 339 '\n' | 355 '\n' |
| 340 ' factory $CTOR(int length) =>\n' | 356 ' factory $CTOR(int length) =>\n' |
| 341 ' $FACTORY.create$(CTOR)(length);\n' | 357 ' $FACTORY.create$(CTOR)(length);\n' |
| 342 '\n' | 358 '\n' |
| 343 ' factory $CTOR.fromList(List<$TYPE> list) =>\n' | 359 ' factory $CTOR.fromList(List<$TYPE> list) =>\n' |
| 344 ' $FACTORY.create$(CTOR)_fromList(list);\n' | 360 ' $FACTORY.create$(CTOR)_fromList(list);\n' |
| 345 '\n' | 361 '\n' |
| 346 ' factory $CTOR.fromBuffer(ArrayBuffer buffer, [int byteOffset, int l
ength]) => \n' | 362 ' factory $CTOR.fromBuffer(ArrayBuffer buffer, [int byteOffset, int l
ength]) => \n' |
| 347 ' $FACTORY.create$(CTOR)_fromBuffer(buffer, byteOffset, length);\n'
, | 363 ' $FACTORY.create$(CTOR)_fromBuffer(buffer, byteOffset, length);\n'
, |
| 348 CTOR=self._interface.id, | 364 CTOR=self._interface.id, |
| 349 TYPE=self._DartType(element_type), | 365 TYPE=self._DartType(typed_array_type), |
| 350 FACTORY=factory_provider) | 366 FACTORY=factory_provider) |
| 351 | 367 |
| 352 events_interface = self._event_generator.ProcessInterface( | 368 events_interface = self._event_generator.ProcessInterface( |
| 353 self._interface, interface_name, | 369 self._interface, interface_name, |
| 354 self._backend.CustomJSMembers(), | 370 self._backend.CustomJSMembers(), |
| 355 interface_emitter, implementation_emitter) | 371 interface_emitter, implementation_emitter) |
| 356 if events_interface: | 372 if events_interface: |
| 357 self._EmitEventGetter(events_interface, '_%sImpl' % events_interface) | 373 self._EmitEventGetter(events_interface, events_interface) |
| 358 | 374 |
| 359 old_backend = self._backend | 375 old_backend = self._backend |
| 360 if not self._backend.ImplementsMergedMembers(): | 376 if not self._backend.ImplementsMergedMembers(): |
| 361 self._backend = HtmlGeneratorDummyBackend() | 377 self._backend = HtmlGeneratorDummyBackend() |
| 362 merged_interface = self._interface_type_info.merged_interface() | 378 merged_interface = self._interface_type_info.merged_interface() |
| 363 if merged_interface: | 379 if merged_interface: |
| 364 self.AddMembers(self._database.GetInterface(merged_interface)) | 380 self.AddMembers(self._database.GetInterface(merged_interface)) |
| 365 self._backend = old_backend | 381 self._backend = old_backend |
| 366 | 382 |
| 367 self.AddMembers(self._interface) | 383 self.AddMembers(self._interface) |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 self._backend.SecondaryContext(interface) | 532 self._backend.SecondaryContext(interface) |
| 517 self.AddOperation(info, True) | 533 self.AddOperation(info, True) |
| 518 | 534 |
| 519 def AddConstant(self, constant): | 535 def AddConstant(self, constant): |
| 520 type = TypeOrNothing(self._DartType(constant.type.id), constant.type.id) | 536 type = TypeOrNothing(self._DartType(constant.type.id), constant.type.id) |
| 521 self._members_emitter.Emit('\n static const $TYPE$NAME = $VALUE;\n', | 537 self._members_emitter.Emit('\n static const $TYPE$NAME = $VALUE;\n', |
| 522 NAME=constant.id, | 538 NAME=constant.id, |
| 523 TYPE=type, | 539 TYPE=type, |
| 524 VALUE=constant.value) | 540 VALUE=constant.value) |
| 525 | 541 |
| 542 self._backend.AddConstant(constant) |
| 543 |
| 526 def _ImplementationEmitter(self): | 544 def _ImplementationEmitter(self): |
| 527 if IsPureInterface(self._interface.id): | |
| 528 return emitter.Emitter() | |
| 529 basename = self._interface_type_info.implementation_name() | 545 basename = self._interface_type_info.implementation_name() |
| 530 if (self._interface_type_info.merged_into() and | 546 if (self._interface_type_info.merged_into() and |
| 531 self._backend.ImplementsMergedMembers()): | 547 self._backend.ImplementsMergedMembers()): |
| 532 # Merged members are implemented in target interface implementation. | 548 # Merged members are implemented in target interface implementation. |
| 533 return emitter.Emitter() | 549 return emitter.Emitter() |
| 534 return self._library_emitter.FileEmitter(basename.lstrip('_')) | 550 return self._library_emitter.FileEmitter(basename) |
| 535 | 551 |
| 536 def _EmitEventGetter(self, events_interface, events_class): | 552 def _EmitEventGetter(self, events_interface, events_class): |
| 537 self._members_emitter.Emit( | 553 self._members_emitter.Emit( |
| 538 '\n /**' | 554 '\n /**' |
| 539 '\n * @domName EventTarget.addEventListener, ' | 555 '\n * @domName EventTarget.addEventListener, ' |
| 540 'EventTarget.removeEventListener, EventTarget.dispatchEvent' | 556 'EventTarget.removeEventListener, EventTarget.dispatchEvent' |
| 541 '\n */' | 557 '\n */' |
| 542 '\n $TYPE get on;\n', | 558 '\n $TYPE get on;\n', |
| 543 TYPE=events_interface) | 559 TYPE=events_interface) |
| 544 | 560 |
| 545 self._implementation_members_emitter.Emit( | 561 self._implementation_members_emitter.Emit( |
| 546 '\n $TYPE get on =>\n new $TYPE(this);\n', | 562 '\n /**' |
| 563 '\n * @domName EventTarget.addEventListener, ' |
| 564 'EventTarget.removeEventListener, EventTarget.dispatchEvent' |
| 565 '\n */' |
| 566 '\n $TYPE get on =>\n new $TYPE._(this);\n', |
| 547 TYPE=events_class) | 567 TYPE=events_class) |
| 548 | 568 |
| 549 def _TransitiveSecondaryParents(self, interface): | 569 def _TransitiveSecondaryParents(self, interface): |
| 550 """Returns a list of all non-primary parents. | 570 """Returns a list of all non-primary parents. |
| 551 | 571 |
| 552 The list contains the interface objects for interfaces defined in the | 572 The list contains the interface objects for interfaces defined in the |
| 553 database, and the name for undefined interfaces. | 573 database, and the name for undefined interfaces. |
| 554 """ | 574 """ |
| 555 def walk(parents): | 575 def walk(parents): |
| 556 for parent in parents: | 576 for parent in parents: |
| (...skipping 29 matching lines...) Expand all Loading... |
| 586 class HtmlGeneratorDummyBackend(object): | 606 class HtmlGeneratorDummyBackend(object): |
| 587 def AddAttribute(self, attribute, html_name, read_only): | 607 def AddAttribute(self, attribute, html_name, read_only): |
| 588 pass | 608 pass |
| 589 | 609 |
| 590 def AddOperation(self, info, html_name): | 610 def AddOperation(self, info, html_name): |
| 591 pass | 611 pass |
| 592 | 612 |
| 593 | 613 |
| 594 # ------------------------------------------------------------------------------ | 614 # ------------------------------------------------------------------------------ |
| 595 | 615 |
| 596 class Dart2JSBackend(object): | 616 class Dart2JSBackend(HtmlDartGenerator): |
| 597 """Generates a dart2js class for the dart:html library from a DOM IDL | 617 """Generates a dart2js class for the dart:html library from a DOM IDL |
| 598 interface. | 618 interface. |
| 599 """ | 619 """ |
| 600 | 620 |
| 601 def __init__(self, interface, options): | 621 def __init__(self, interface, options): |
| 602 self._interface = interface | 622 super(Dart2JSBackend, self).__init__(interface, options) |
| 623 |
| 603 self._database = options.database | 624 self._database = options.database |
| 604 self._template_loader = options.templates | 625 self._template_loader = options.templates |
| 605 self._type_registry = options.type_registry | 626 self._type_registry = options.type_registry |
| 627 self._renamer = options.renamer |
| 606 self._interface_type_info = self._type_registry.TypeInfo(self._interface.id) | 628 self._interface_type_info = self._type_registry.TypeInfo(self._interface.id) |
| 607 self._current_secondary_parent = None | 629 self._current_secondary_parent = None |
| 608 | 630 |
| 609 def ImplementsMergedMembers(self): | 631 def ImplementsMergedMembers(self): |
| 610 return True | 632 return True |
| 611 | 633 |
| 612 def GenerateCallback(self, info): | 634 def GenerateCallback(self, info): |
| 613 pass | 635 pass |
| 614 | 636 |
| 615 def RootClassName(self): | 637 def RootClassName(self): |
| 616 return None | 638 return None |
| 617 | 639 |
| 618 def AdditionalImplementedInterfaces(self): | 640 def AdditionalImplementedInterfaces(self): |
| 619 # TODO: Include all implemented interfaces, including other Lists. | 641 implements = super(Dart2JSBackend, self).AdditionalImplementedInterfaces() |
| 620 implements = [] | |
| 621 if self._interface_type_info.is_typed_array(): | |
| 622 element_type = self._interface_type_info.list_item_type() | |
| 623 implements.append('List<%s>' % self._DartType(element_type)) | |
| 624 if self._interface_type_info.list_item_type(): | 642 if self._interface_type_info.list_item_type(): |
| 625 implements.append('JavaScriptIndexingBehavior') | 643 implements.append('JavaScriptIndexingBehavior') |
| 626 return implements | 644 return implements |
| 627 | 645 |
| 628 def NativeSpec(self): | 646 def NativeSpec(self): |
| 629 native_spec = MakeNativeSpec(self._interface.javascript_binding_name) | 647 native_spec = MakeNativeSpec(self._interface.javascript_binding_name) |
| 630 return ' native "%s"' % native_spec | 648 return ' native "%s"' % native_spec |
| 631 | 649 |
| 632 def ImplementationTemplate(self): | 650 def ImplementationTemplate(self): |
| 651 if IsPureInterface(self._interface.id): |
| 652 return self._template_loader.Load('pure_interface.darttemplate') |
| 653 |
| 633 template_file = ('impl_%s.darttemplate' % | 654 template_file = ('impl_%s.darttemplate' % |
| 634 self._interface_type_info.interface_name()) | 655 self._interface_type_info.interface_name()) |
| 635 return (self._template_loader.TryLoad(template_file) or | 656 return (self._template_loader.TryLoad(template_file) or |
| 636 self._template_loader.Load('dart2js_impl.darttemplate')) | 657 self._template_loader.Load('dart2js_impl.darttemplate')) |
| 637 | 658 |
| 638 def StartInterface(self, emitter): | 659 def StartInterface(self, emitter): |
| 639 self._members_emitter = emitter | 660 self._members_emitter = emitter |
| 640 | 661 |
| 641 def FinishInterface(self): | 662 def FinishInterface(self): |
| 642 pass | 663 pass |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 has_contains = any(op.id == 'contains' for op in self._interface.operation
s) | 736 has_contains = any(op.id == 'contains' for op in self._interface.operation
s) |
| 716 template = self._template_loader.Load( | 737 template = self._template_loader.Load( |
| 717 template_file, | 738 template_file, |
| 718 {'DEFINE_CONTAINS': not has_contains}) | 739 {'DEFINE_CONTAINS': not has_contains}) |
| 719 self._members_emitter.Emit(template, E=self._DartType(element_type)) | 740 self._members_emitter.Emit(template, E=self._DartType(element_type)) |
| 720 | 741 |
| 721 def AddAttribute(self, attribute, html_name, read_only): | 742 def AddAttribute(self, attribute, html_name, read_only): |
| 722 if self._HasCustomImplementation(attribute.id): | 743 if self._HasCustomImplementation(attribute.id): |
| 723 return | 744 return |
| 724 | 745 |
| 746 if IsPureInterface(self._interface.id): |
| 747 self._AddInterfaceAttribute(attribute) |
| 748 return |
| 749 |
| 725 if attribute.id != html_name: | 750 if attribute.id != html_name: |
| 726 self._AddAttributeUsingProperties(attribute, html_name, read_only) | 751 self._AddAttributeUsingProperties(attribute, html_name, read_only) |
| 727 return | 752 return |
| 728 | 753 |
| 729 # If the attribute is shadowing, we can't generate a shadowing | 754 # If the attribute is shadowing, we can't generate a shadowing |
| 730 # field (Issue 1633). | 755 # field (Issue 1633). |
| 731 # TODO(sra): _FindShadowedAttribute does not take into account the html | 756 # TODO(sra): _FindShadowedAttribute does not take into account the html |
| 732 # renaming. we should be looking for another attribute that has the same | 757 # renaming. we should be looking for another attribute that has the same |
| 733 # html_name. Two attributes with the same IDL name might not match if one | 758 # html_name. Two attributes with the same IDL name might not match if one |
| 734 # is renamed. | 759 # is renamed. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 753 | 778 |
| 754 # If the type has a conversion we need a getter or setter to contain the | 779 # If the type has a conversion we need a getter or setter to contain the |
| 755 # conversion code. | 780 # conversion code. |
| 756 if (self._OutputConversion(attribute.type.id, attribute.id) or | 781 if (self._OutputConversion(attribute.type.id, attribute.id) or |
| 757 self._InputConversion(attribute.type.id, attribute.id)): | 782 self._InputConversion(attribute.type.id, attribute.id)): |
| 758 self._AddAttributeUsingProperties(attribute, html_name, read_only) | 783 self._AddAttributeUsingProperties(attribute, html_name, read_only) |
| 759 return | 784 return |
| 760 | 785 |
| 761 output_type = self._NarrowOutputType(attribute.type.id) | 786 output_type = self._NarrowOutputType(attribute.type.id) |
| 762 input_type = self._NarrowInputType(attribute.type.id) | 787 input_type = self._NarrowInputType(attribute.type.id) |
| 788 self.EmitAttributeDocumentation(attribute) |
| 763 if not read_only: | 789 if not read_only: |
| 764 self._members_emitter.Emit( | 790 self._members_emitter.Emit( |
| 765 '\n $TYPE $NAME;' | 791 '\n $TYPE $NAME;' |
| 766 '\n', | 792 '\n', |
| 767 NAME=DartDomNameOfAttribute(attribute), | 793 NAME=DartDomNameOfAttribute(attribute), |
| 768 TYPE=output_type) | 794 TYPE=output_type) |
| 769 else: | 795 else: |
| 770 self._members_emitter.Emit( | 796 self._members_emitter.Emit( |
| 771 '\n final $TYPE $NAME;' | 797 '\n final $TYPE $NAME;' |
| 772 '\n', | 798 '\n', |
| 773 NAME=DartDomNameOfAttribute(attribute), | 799 NAME=DartDomNameOfAttribute(attribute), |
| 774 TYPE=output_type) | 800 TYPE=output_type) |
| 775 | 801 |
| 776 def _AddAttributeUsingProperties(self, attribute, html_name, read_only): | 802 def _AddAttributeUsingProperties(self, attribute, html_name, read_only): |
| 777 self._AddRenamingGetter(attribute, html_name) | 803 self._AddRenamingGetter(attribute, html_name) |
| 778 if not read_only: | 804 if not read_only: |
| 779 self._AddRenamingSetter(attribute, html_name) | 805 self._AddRenamingSetter(attribute, html_name) |
| 780 | 806 |
| 807 def _AddInterfaceAttribute(self, attribute): |
| 808 self._members_emitter.Emit( |
| 809 '\n $TYPE $NAME;' |
| 810 '\n', |
| 811 NAME=DartDomNameOfAttribute(attribute), |
| 812 TYPE=self._NarrowOutputType(attribute.type.id)) |
| 813 |
| 781 def _AddRenamingGetter(self, attr, html_name): | 814 def _AddRenamingGetter(self, attr, html_name): |
| 815 self.EmitAttributeDocumentation(attr) |
| 816 |
| 782 conversion = self._OutputConversion(attr.type.id, attr.id) | 817 conversion = self._OutputConversion(attr.type.id, attr.id) |
| 783 if conversion: | 818 if conversion: |
| 784 return self._AddConvertingGetter(attr, html_name, conversion) | 819 return self._AddConvertingGetter(attr, html_name, conversion) |
| 785 return_type = self._NarrowOutputType(attr.type.id) | 820 return_type = self._NarrowOutputType(attr.type.id) |
| 786 self._members_emitter.Emit( | 821 self._members_emitter.Emit( |
| 787 # TODO(sra): Use metadata to provide native name. | 822 # TODO(sra): Use metadata to provide native name. |
| 788 '\n $TYPE get $HTML_NAME => JS("$TYPE", "#.$NAME", this);' | 823 '\n $TYPE get $HTML_NAME => JS("$TYPE", "#.$NAME", this);' |
| 789 '\n', | 824 '\n', |
| 790 HTML_NAME=html_name, | 825 HTML_NAME=html_name, |
| 791 NAME=attr.id, | 826 NAME=attr.id, |
| 792 TYPE=return_type) | 827 TYPE=return_type) |
| 793 | 828 |
| 794 def _AddRenamingSetter(self, attr, html_name): | 829 def _AddRenamingSetter(self, attr, html_name): |
| 830 self.EmitAttributeDocumentation(attr) |
| 831 |
| 795 conversion = self._InputConversion(attr.type.id, attr.id) | 832 conversion = self._InputConversion(attr.type.id, attr.id) |
| 796 if conversion: | 833 if conversion: |
| 797 return self._AddConvertingSetter(attr, html_name, conversion) | 834 return self._AddConvertingSetter(attr, html_name, conversion) |
| 798 self._members_emitter.Emit( | 835 self._members_emitter.Emit( |
| 799 # TODO(sra): Use metadata to provide native name. | 836 # TODO(sra): Use metadata to provide native name. |
| 800 '\n void set $HTML_NAME($TYPE value) {' | 837 '\n void set $HTML_NAME($TYPE value) {' |
| 801 '\n JS("void", "#.$NAME = #", this, value);' | 838 '\n JS("void", "#.$NAME = #", this, value);' |
| 802 '\n }' | 839 '\n }' |
| 803 '\n', | 840 '\n', |
| 804 HTML_NAME=html_name, | 841 HTML_NAME=html_name, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 838 pass | 875 pass |
| 839 | 876 |
| 840 def AddOperation(self, info, html_name): | 877 def AddOperation(self, info, html_name): |
| 841 """ | 878 """ |
| 842 Arguments: | 879 Arguments: |
| 843 info: An OperationInfo object. | 880 info: An OperationInfo object. |
| 844 """ | 881 """ |
| 845 if self._HasCustomImplementation(info.name): | 882 if self._HasCustomImplementation(info.name): |
| 846 return | 883 return |
| 847 | 884 |
| 848 # Any conversions needed? | 885 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */', |
| 849 if any(self._OperationRequiresConversions(op) for op in info.overloads): | 886 DOMINTERFACE=info.overloads[0].doc_js_interface_name, |
| 887 DOMNAME=info.name) |
| 888 |
| 889 if IsPureInterface(self._interface.id): |
| 890 self._AddInterfaceOperation(info, html_name) |
| 891 elif any(self._OperationRequiresConversions(op) for op in info.overloads): |
| 892 # Any conversions needed? |
| 850 self._AddOperationWithConversions(info, html_name) | 893 self._AddOperationWithConversions(info, html_name) |
| 851 else: | 894 else: |
| 852 self._AddDirectNativeOperation(info, html_name) | 895 self._AddDirectNativeOperation(info, html_name) |
| 853 | 896 |
| 854 def _AddDirectNativeOperation(self, info, html_name): | 897 def _AddDirectNativeOperation(self, info, html_name): |
| 855 # Do we need a native body? | 898 # Do we need a native body? |
| 856 if html_name != info.declared_name: | 899 if html_name != info.declared_name: |
| 857 return_type = self._NarrowOutputType(info.type_name) | 900 return_type = self._NarrowOutputType(info.type_name) |
| 858 | 901 |
| 859 operation_emitter = self._members_emitter.Emit('$!SCOPE', | 902 operation_emitter = self._members_emitter.Emit('$!SCOPE', |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1008 else: | 1051 else: |
| 1009 operation = operations[0] | 1052 operation = operations[0] |
| 1010 argument_count = len(operation.arguments) | 1053 argument_count = len(operation.arguments) |
| 1011 for position, argument in list(enumerate(operation.arguments))[::-1]: | 1054 for position, argument in list(enumerate(operation.arguments))[::-1]: |
| 1012 if self._IsOptional(operation, argument): | 1055 if self._IsOptional(operation, argument): |
| 1013 check = '?%s' % parameter_names[position] | 1056 check = '?%s' % parameter_names[position] |
| 1014 GenerateCall(operation, position + 1, [check]) | 1057 GenerateCall(operation, position + 1, [check]) |
| 1015 argument_count = position | 1058 argument_count = position |
| 1016 GenerateCall(operation, argument_count, []) | 1059 GenerateCall(operation, argument_count, []) |
| 1017 | 1060 |
| 1061 def _AddInterfaceOperation(self, info, html_name): |
| 1062 self._members_emitter.Emit( |
| 1063 '\n' |
| 1064 ' $TYPE $NAME($PARAMS);\n', |
| 1065 TYPE=self._NarrowOutputType(info.type_name), |
| 1066 NAME=info.name, |
| 1067 PARAMS=info.ParametersDeclaration(self._NarrowInputType)) |
| 1068 |
| 1069 def AddConstant(self, constant): |
| 1070 type = TypeOrNothing(self._DartType(constant.type.id), constant.type.id) |
| 1071 self._members_emitter.Emit('\n static const $TYPE$NAME = $VALUE;\n', |
| 1072 NAME=constant.id, |
| 1073 TYPE=type, |
| 1074 VALUE=constant.value) |
| 1018 | 1075 |
| 1019 def _IsOptional(self, operation, argument): | 1076 def _IsOptional(self, operation, argument): |
| 1020 return IsOptional(argument) | 1077 return IsOptional(argument) |
| 1021 | 1078 |
| 1022 | 1079 |
| 1023 def _OperationRequiresConversions(self, operation): | 1080 def _OperationRequiresConversions(self, operation): |
| 1024 return (self._OperationRequiresOutputConversion(operation) or | 1081 return (self._OperationRequiresOutputConversion(operation) or |
| 1025 self._OperationRequiresInputConversions(operation)) | 1082 self._OperationRequiresInputConversions(operation)) |
| 1026 | 1083 |
| 1027 def _OperationRequiresOutputConversion(self, operation): | 1084 def _OperationRequiresOutputConversion(self, operation): |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1045 def CustomJSMembers(self): | 1102 def CustomJSMembers(self): |
| 1046 return _js_custom_members | 1103 return _js_custom_members |
| 1047 | 1104 |
| 1048 def _NarrowToImplementationType(self, type_name): | 1105 def _NarrowToImplementationType(self, type_name): |
| 1049 return self._type_registry.TypeInfo(type_name).narrow_dart_type() | 1106 return self._type_registry.TypeInfo(type_name).narrow_dart_type() |
| 1050 | 1107 |
| 1051 def _NarrowInputType(self, type_name): | 1108 def _NarrowInputType(self, type_name): |
| 1052 return self._NarrowToImplementationType(type_name) | 1109 return self._NarrowToImplementationType(type_name) |
| 1053 | 1110 |
| 1054 def _NarrowOutputType(self, type_name): | 1111 def _NarrowOutputType(self, type_name): |
| 1055 secure_name = SecureOutputType(self, type_name, True) | 1112 return SecureOutputType(self, type_name) |
| 1056 return self._NarrowToImplementationType(secure_name) | |
| 1057 | 1113 |
| 1058 def _FindShadowedAttribute(self, attr): | 1114 def _FindShadowedAttribute(self, attr): |
| 1059 """Returns (attribute, superinterface) or (None, None).""" | 1115 """Returns (attribute, superinterface) or (None, None).""" |
| 1060 def FindInParent(interface): | 1116 def FindInParent(interface): |
| 1061 """Returns matching attribute in parent, or None.""" | 1117 """Returns matching attribute in parent, or None.""" |
| 1062 if interface.parents: | 1118 if interface.parents: |
| 1063 parent = interface.parents[0] | 1119 parent = interface.parents[0] |
| 1064 if IsDartCollectionType(parent.type.id): | 1120 if IsDartCollectionType(parent.type.id): |
| 1065 return (None, None) | 1121 return (None, None) |
| 1066 if IsPureInterface(parent.type.id): | 1122 if IsPureInterface(parent.type.id): |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1119 | 1175 |
| 1120 library_emitter = self._multiemitter.FileEmitter(library_file_path) | 1176 library_emitter = self._multiemitter.FileEmitter(library_file_path) |
| 1121 library_file_dir = os.path.dirname(library_file_path) | 1177 library_file_dir = os.path.dirname(library_file_path) |
| 1122 auxiliary_dir = os.path.relpath(auxiliary_dir, library_file_dir) | 1178 auxiliary_dir = os.path.relpath(auxiliary_dir, library_file_dir) |
| 1123 imports_emitter = library_emitter.Emit( | 1179 imports_emitter = library_emitter.Emit( |
| 1124 self._template, AUXILIARY_DIR=massage_path(auxiliary_dir)) | 1180 self._template, AUXILIARY_DIR=massage_path(auxiliary_dir)) |
| 1125 for path in sorted(self._path_to_emitter.keys()): | 1181 for path in sorted(self._path_to_emitter.keys()): |
| 1126 relpath = os.path.relpath(path, library_file_dir) | 1182 relpath = os.path.relpath(path, library_file_dir) |
| 1127 imports_emitter.Emit( | 1183 imports_emitter.Emit( |
| 1128 "part '$PATH';\n", PATH=massage_path(relpath)) | 1184 "part '$PATH';\n", PATH=massage_path(relpath)) |
| OLD | NEW |