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