| 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 | 10 |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 infos = _html_element_constructors[typename] | 325 infos = _html_element_constructors[typename] |
| 326 if isinstance(infos, str): | 326 if isinstance(infos, str): |
| 327 infos = ElementConstructorInfo(tag=infos) | 327 infos = ElementConstructorInfo(tag=infos) |
| 328 if not isinstance(infos, list): | 328 if not isinstance(infos, list): |
| 329 infos = [infos] | 329 infos = [infos] |
| 330 return infos | 330 return infos |
| 331 | 331 |
| 332 def EmitHtmlElementFactoryConstructors(emitter, infos, typename, class_name): | 332 def EmitHtmlElementFactoryConstructors(emitter, infos, typename, class_name): |
| 333 for info in infos: | 333 for info in infos: |
| 334 constructor_info = info.ConstructorInfo(typename) | 334 constructor_info = info.ConstructorInfo(typename) |
| 335 |
| 335 inits = emitter.Emit( | 336 inits = emitter.Emit( |
| 336 '\n' | 337 '\n' |
| 337 ' factory $CONSTRUCTOR($PARAMS) {\n' | 338 ' static $RETURN_TYPE $CONSTRUCTOR($PARAMS) {\n' |
| 338 ' $CLASS _e = _document.$dom_createElement("$TAG");\n' | 339 ' $CLASS _e = _document.$dom_createElement("$TAG");\n' |
| 339 '$!INITS' | 340 '$!INITS' |
| 340 ' return _e;\n' | 341 ' return _e;\n' |
| 341 ' }\n', | 342 ' }\n', |
| 342 CONSTRUCTOR=constructor_info.ConstructorFullName(), | 343 RETURN_TYPE=constructor_info.type_name, |
| 344 CONSTRUCTOR=constructor_info.ConstructorFactoryName(DartType), |
| 343 CLASS=class_name, | 345 CLASS=class_name, |
| 344 TAG=info.tag, | 346 TAG=info.tag, |
| 345 PARAMS=constructor_info.ParametersInterfaceDeclaration(DartType)) | 347 PARAMS=constructor_info.ParametersInterfaceDeclaration(DartType)) |
| 346 for param in constructor_info.param_infos: | 348 for param in constructor_info.param_infos: |
| 347 inits.Emit(' if ($E != null) _e.$E = $E;\n', E=param.name) | 349 inits.Emit(' if ($E != null) _e.$E = $E;\n', E=param.name) |
| 348 | 350 |
| 349 | 351 |
| 350 # These classes require an explicit declaration for the "on" method even though | 352 # These classes require an explicit declaration for the "on" method even though |
| 351 # they don't declare any unique events, because the concrete class hierarchy | 353 # they don't declare any unique events, because the concrete class hierarchy |
| 352 # doesn't match the interface hierarchy. | 354 # doesn't match the interface hierarchy. |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 self._interface_emitter = self._system._emitters.FileEmitter(path) | 481 self._interface_emitter = self._system._emitters.FileEmitter(path) |
| 480 else: | 482 else: |
| 481 self._interface_emitter = emitter.Emitter() | 483 self._interface_emitter = emitter.Emitter() |
| 482 | 484 |
| 483 template_file = 'interface_%s.darttemplate' % self._html_interface_name | 485 template_file = 'interface_%s.darttemplate' % self._html_interface_name |
| 484 interface_template = (self._system._templates.TryLoad(template_file) or | 486 interface_template = (self._system._templates.TryLoad(template_file) or |
| 485 self._system._templates.Load('interface.darttemplate')
) | 487 self._system._templates.Load('interface.darttemplate')
) |
| 486 | 488 |
| 487 typename = self._html_interface_name | 489 typename = self._html_interface_name |
| 488 | 490 |
| 489 extends = [] | 491 implements = [] |
| 490 suppressed_extends = [] | 492 suppressed_implements = [] |
| 491 | 493 |
| 492 for parent in self._interface.parents: | 494 for parent in self._interface.parents: |
| 493 # TODO(vsm): Remove source_filter. | 495 # TODO(vsm): Remove source_filter. |
| 494 if MatchSourceFilter(parent): | 496 if MatchSourceFilter(parent): |
| 495 # Parent is a DOM type. | 497 # Parent is a DOM type. |
| 496 extends.append(self._DartType(parent.type.id)) | 498 implements.append(self._DartType(parent.type.id)) |
| 497 elif '<' in parent.type.id: | 499 elif '<' in parent.type.id: |
| 498 # Parent is a Dart collection type. | 500 # Parent is a Dart collection type. |
| 499 # TODO(vsm): Make this check more robust. | 501 # TODO(vsm): Make this check more robust. |
| 500 extends.append(self._DartType(parent.type.id)) | 502 implements.append(self._DartType(parent.type.id)) |
| 501 else: | 503 else: |
| 502 suppressed_extends.append('%s.%s' % | 504 suppressed_implements.append('%s.%s' % |
| 503 (self._common_prefix, self._DartType(parent.type.id))) | 505 (self._common_prefix, self._DartType(parent.type.id))) |
| 504 | 506 |
| 505 comment = ' extends' | 507 comment = ' extends' |
| 506 extends_str = '' | 508 implements_str = '' |
| 507 if extends: | 509 if implements: |
| 508 extends_str += ' extends ' + ', '.join(extends) | 510 implements_str += ' implements ' + ', '.join(implements) |
| 509 comment = ',' | 511 comment = ',' |
| 510 if suppressed_extends: | 512 if suppressed_implements: |
| 511 extends_str += ' /*%s %s */' % (comment, ', '.join(suppressed_extends)) | 513 implements_str += ' /*%s %s */' % (comment, |
| 514 ', '.join(suppressed_implements)) |
| 512 | 515 |
| 513 factory_provider = None | 516 factory_provider = None |
| 514 if typename in interface_factories: | 517 if typename in interface_factories: |
| 515 factory_provider = interface_factories[typename] | 518 factory_provider = interface_factories[typename] |
| 516 | 519 |
| 517 constructors = [] | 520 constructors = [] |
| 518 constructor_info = AnalyzeConstructor(self._interface) | 521 constructor_info = AnalyzeConstructor(self._interface) |
| 519 if constructor_info: | 522 if constructor_info: |
| 520 constructors.append(constructor_info) | 523 constructors.append(constructor_info) |
| 521 factory_provider = '_' + typename + 'FactoryProvider' | 524 factory_provider = '_' + typename + 'FactoryProvider' |
| (...skipping 18 matching lines...) Expand all Loading... |
| 540 self._html_interface_name, | 543 self._html_interface_name, |
| 541 self._backend.ImplementationClassName()) | 544 self._backend.ImplementationClassName()) |
| 542 | 545 |
| 543 for info in infos: | 546 for info in infos: |
| 544 constructors.append(info.ConstructorInfo(typename)) | 547 constructors.append(info.ConstructorInfo(typename)) |
| 545 if factory_provider: | 548 if factory_provider: |
| 546 assert factory_provider == info.factory_provider_name | 549 assert factory_provider == info.factory_provider_name |
| 547 else: | 550 else: |
| 548 factory_provider = info.factory_provider_name | 551 factory_provider = info.factory_provider_name |
| 549 | 552 |
| 550 if factory_provider: | |
| 551 extends_str += ' default ' + factory_provider | |
| 552 | |
| 553 # TODO(vsm): Add appropriate package / namespace syntax. | 553 # TODO(vsm): Add appropriate package / namespace syntax. |
| 554 (self._type_comment_emitter, | 554 (self._type_comment_emitter, |
| 555 self._members_emitter, | 555 self._members_emitter, |
| 556 self._top_level_emitter) = self._interface_emitter.Emit( | 556 self._top_level_emitter) = self._interface_emitter.Emit( |
| 557 interface_template + '$!TOP_LEVEL', | 557 interface_template + '$!TOP_LEVEL', |
| 558 ID=typename, | 558 ID=typename, |
| 559 EXTENDS=extends_str) | 559 EXTENDS=implements_str) |
| 560 | 560 |
| 561 self._type_comment_emitter.Emit("/// @domName $DOMNAME", | 561 self._type_comment_emitter.Emit("/// @domName $DOMNAME", |
| 562 DOMNAME=self._interface.doc_js_name) | 562 DOMNAME=self._interface.doc_js_name) |
| 563 | 563 |
| 564 if self._backend.HasImplementation(): | 564 if self._backend.HasImplementation(): |
| 565 path = self._backend.FilePathForDartImplementation() | 565 path = self._backend.FilePathForDartImplementation() |
| 566 self._system._dart_interface_file_paths.append(path) | 566 self._system._dart_interface_file_paths.append(path) |
| 567 self._implementation_emitter = self._system._emitters.FileEmitter(path) | 567 self._implementation_emitter = self._system._emitters.FileEmitter(path) |
| 568 else: | 568 else: |
| 569 self._implementation_emitter = emitter.Emitter() | 569 self._implementation_emitter = emitter.Emitter() |
| 570 self._backend.SetImplementationEmitter(self._implementation_emitter) | 570 self._backend.SetImplementationEmitter(self._implementation_emitter) |
| 571 self._implementation_members_emitter = self._backend.StartInterface() | 571 self._implementation_members_emitter = self._backend.StartInterface() |
| 572 | 572 |
| 573 for constructor_info in constructors: | 573 for constructor_info in constructors: |
| 574 self._members_emitter.Emit( | 574 constructor_info.GenerateFactoryInvocation( |
| 575 '\n' | 575 self._DartType, self._members_emitter, factory_provider) |
| 576 ' $CTOR($PARAMS);\n', | |
| 577 CTOR=self._DartType(constructor_info.ConstructorFullName()), | |
| 578 PARAMS=constructor_info.ParametersInterfaceDeclaration(self._DartType)
) | |
| 579 | 576 |
| 580 element_type = MaybeTypedArrayElementTypeInHierarchy( | 577 element_type = MaybeTypedArrayElementTypeInHierarchy( |
| 581 self._interface, self._system._database) | 578 self._interface, self._system._database) |
| 582 if element_type: | 579 if element_type: |
| 583 self._members_emitter.Emit( | 580 self._members_emitter.Emit( |
| 584 '\n' | 581 '\n' |
| 585 ' $CTOR(int length);\n' | 582 ' factory $CTOR(int length) =>\n' |
| 583 ' $FACTORY.create$(CTOR)(length);\n' |
| 586 '\n' | 584 '\n' |
| 587 ' $CTOR.fromList(List<$TYPE> list);\n' | 585 ' factory $CTOR.fromList(List<$TYPE> list) =>\n' |
| 586 ' $FACTORY.create$(CTOR)_fromList(list);\n' |
| 588 '\n' | 587 '\n' |
| 589 ' $CTOR.fromBuffer(ArrayBuffer buffer,' | 588 ' factory $CTOR.fromBuffer(ArrayBuffer buffer, [int byteOffset, int l
ength]) => \n' |
| 590 ' [int byteOffset, int length]);\n', | 589 ' $FACTORY.create$(CTOR)_fromBuffer(buffer, byteOffset, length);\n'
, |
| 591 CTOR=self._interface.id, | 590 CTOR=self._interface.id, |
| 592 TYPE=self._DartType(element_type)) | 591 TYPE=self._DartType(element_type), |
| 592 FACTORY=factory_provider) |
| 593 | 593 |
| 594 self._GenerateEvents() | 594 self._GenerateEvents() |
| 595 | 595 |
| 596 old_backend = self._backend | 596 old_backend = self._backend |
| 597 if not self._backend.ImplementsMergedMembers(): | 597 if not self._backend.ImplementsMergedMembers(): |
| 598 self._backend = HtmlGeneratorDummyBackend() | 598 self._backend = HtmlGeneratorDummyBackend() |
| 599 for merged_interface in _merged_html_interfaces: | 599 for merged_interface in _merged_html_interfaces: |
| 600 if _merged_html_interfaces[merged_interface] == self._interface.id: | 600 if _merged_html_interfaces[merged_interface] == self._interface.id: |
| 601 merged_interface = self._database.GetInterface(merged_interface) | 601 merged_interface = self._database.GetInterface(merged_interface) |
| 602 self.AddMembers(merged_interface) | 602 self.AddMembers(merged_interface) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 620 self._interface.id, dom_name, 'set:') | 620 self._interface.id, dom_name, 'set:') |
| 621 read_only = IsReadOnly(attribute) or not html_setter_name | 621 read_only = IsReadOnly(attribute) or not html_setter_name |
| 622 | 622 |
| 623 # We don't yet handle inconsistent renames of the getter and setter yet. | 623 # We don't yet handle inconsistent renames of the getter and setter yet. |
| 624 assert(not html_setter_name or html_name == html_setter_name) | 624 assert(not html_setter_name or html_name == html_setter_name) |
| 625 | 625 |
| 626 if not is_secondary: | 626 if not is_secondary: |
| 627 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */', | 627 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */', |
| 628 DOMINTERFACE=attribute.doc_js_interface_name, | 628 DOMINTERFACE=attribute.doc_js_interface_name, |
| 629 DOMNAME=dom_name) | 629 DOMNAME=dom_name) |
| 630 modifier = 'final ' if read_only else '' | 630 if read_only: |
| 631 self._members_emitter.Emit('\n $MODIFIER$TYPE $NAME;\n', | 631 template = '\n abstract $TYPE get $NAME;\n' |
| 632 MODIFIER=modifier, | 632 else: |
| 633 template = '\n $TYPE $NAME;\n' |
| 634 |
| 635 self._members_emitter.Emit(template, |
| 633 NAME=html_name, | 636 NAME=html_name, |
| 634 TYPE=self._DartType(attribute.type.id)) | 637 TYPE=self._DartType(attribute.type.id)) |
| 638 |
| 635 self._backend.AddAttribute(attribute, html_name, read_only) | 639 self._backend.AddAttribute(attribute, html_name, read_only) |
| 636 | 640 |
| 637 def AddSecondaryAttribute(self, interface, attribute): | 641 def AddSecondaryAttribute(self, interface, attribute): |
| 638 self._backend.SecondaryContext(interface) | 642 self._backend.SecondaryContext(interface) |
| 639 self.AddAttribute(attribute, True) | 643 self.AddAttribute(attribute, True) |
| 640 | 644 |
| 641 def AddOperation(self, info, skip_declaration=False): | 645 def AddOperation(self, info, skip_declaration=False): |
| 642 """ | 646 """ |
| 643 Arguments: | 647 Arguments: |
| 644 operations - contains the overloads, one or more operations with the same | 648 operations - contains the overloads, one or more operations with the same |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 parent_events_interface = self._shared.GetParentEventsClass(self._interface) | 696 parent_events_interface = self._shared.GetParentEventsClass(self._interface) |
| 693 parent_events_class = '_%sImpl' % parent_events_interface | 697 parent_events_class = '_%sImpl' % parent_events_interface |
| 694 | 698 |
| 695 if not event_attrs: | 699 if not event_attrs: |
| 696 self._EmitEventGetter(parent_events_interface, parent_events_class) | 700 self._EmitEventGetter(parent_events_interface, parent_events_class) |
| 697 return | 701 return |
| 698 | 702 |
| 699 self._EmitEventGetter(events_interface, events_class) | 703 self._EmitEventGetter(events_interface, events_class) |
| 700 | 704 |
| 701 events_members = self._interface_emitter.Emit( | 705 events_members = self._interface_emitter.Emit( |
| 702 '\ninterface $INTERFACE extends $PARENTS {\n$!MEMBERS}\n', | 706 '\nabstract class $INTERFACE implements $PARENTS {\n$!MEMBERS}\n', |
| 703 INTERFACE=events_interface, | 707 INTERFACE=events_interface, |
| 704 PARENTS=', '.join( | 708 PARENTS=', '.join( |
| 705 self._shared.GetParentsEventsClasses(self._interface))) | 709 self._shared.GetParentsEventsClasses(self._interface))) |
| 706 | 710 |
| 707 # TODO(jacobr): specify the type of _ptr as EventTarget | 711 # TODO(jacobr): specify the type of _ptr as EventTarget |
| 708 implementation_events_members = self._implementation_emitter.Emit( | 712 implementation_events_members = self._implementation_emitter.Emit( |
| 709 '\n' | 713 '\n' |
| 710 'class $CLASSNAME extends $SUPER implements $INTERFACE {\n' | 714 'class $CLASSNAME extends $SUPER implements $INTERFACE {\n' |
| 711 ' $CLASSNAME(_ptr) : super(_ptr);\n' | 715 ' $CLASSNAME(_ptr) : super(_ptr);\n' |
| 712 '$!MEMBERS}\n', | 716 '$!MEMBERS}\n', |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1234 return HtmlDart2JSClassGenerator(self, interface) | 1238 return HtmlDart2JSClassGenerator(self, interface) |
| 1235 | 1239 |
| 1236 def GenerateLibraries(self, dart_files): | 1240 def GenerateLibraries(self, dart_files): |
| 1237 self._GenerateLibFile( | 1241 self._GenerateLibFile( |
| 1238 'html_dart2js.darttemplate', | 1242 'html_dart2js.darttemplate', |
| 1239 os.path.join(self._output_dir, 'html_dart2js.dart'), | 1243 os.path.join(self._output_dir, 'html_dart2js.dart'), |
| 1240 dart_files) | 1244 dart_files) |
| 1241 | 1245 |
| 1242 def Finish(self): | 1246 def Finish(self): |
| 1243 pass | 1247 pass |
| OLD | NEW |