Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(153)

Side by Side Diff: client/dom/scripts/dartgenerator.py

Issue 9181010: Refactor DOM generator. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « client/dom/generated/src/wrapping/_StorageWrappingImplementation.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 2 # Copyright (c) 2011, 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 generates Dart APIs from the IDL database.""" 6 """This module generates Dart APIs from the IDL database."""
7 7
8 import emitter 8 import emitter
9 import idlnode 9 import idlnode
10 import logging 10 import logging
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 super_database -- database containing super interfaces that the generated 372 super_database -- database containing super interfaces that the generated
373 interfaces should extend. 373 interfaces should extend.
374 common_prefix -- prefix for the common library, if any. 374 common_prefix -- prefix for the common library, if any.
375 lib_file_path -- filename for generated .lib file, None if not required. 375 lib_file_path -- filename for generated .lib file, None if not required.
376 lib_template -- template file in this directory for generated lib file. 376 lib_template -- template file in this directory for generated lib file.
377 """ 377 """
378 378
379 self._emitters = multiemitter.MultiEmitter() 379 self._emitters = multiemitter.MultiEmitter()
380 self._database = database 380 self._database = database
381 self._output_dir = output_dir 381 self._output_dir = output_dir
382 self._dart_callback_file_paths = []
383 382
384 self._ComputeInheritanceClosure() 383 self._ComputeInheritanceClosure()
385 self._StartGenerateInterfaceLibrary() 384
386 self._StartGenerateWrappingImpl(output_dir) 385 interface_system = WrappingInterfacesSystem(
387 self._StartGenerateFrogImpl(output_dir) 386 self._database, self._emitters, self._output_dir)
387
388 wrapping_system = WrappingImplementationSystem(
389 self._database, self._emitters, self._output_dir)
390
391 # Makes wrapper implementations available for listing in interface lib.
392 interface_system._implementation_system = wrapping_system
393
394 frog_system = FrogSystem(
395 self._database, self._emitters, self._output_dir)
396
397 self._systems = [interface_system,
398 wrapping_system,
399 frog_system]
388 400
389 # Render all interfaces into Dart and save them in files. 401 # Render all interfaces into Dart and save them in files.
390 dart_file_paths = []
391 processed_interfaces = []
392 for interface in database.GetInterfaces(): 402 for interface in database.GetInterfaces():
393 403
394 super_interface = None 404 super_interface = None
395 super_name = interface.id 405 super_name = interface.id
396 406
397 if not _MatchSourceFilter(source_filter, interface): 407 if not _MatchSourceFilter(source_filter, interface):
398 # Skip this interface since it's not present in the required source 408 # Skip this interface since it's not present in the required source
399 _logger.info('Omitting interface - %s' % interface.id) 409 _logger.info('Omitting interface - %s' % interface.id)
400 continue 410 continue
401 411
402 if super_name in super_map: 412 if super_name in super_map:
403 super_name = super_map[super_name] 413 super_name = super_map[super_name]
404 414
405 if (super_database is not None and 415 if (super_database is not None and
406 super_database.HasInterface(super_name)): 416 super_database.HasInterface(super_name)):
407 super_interface = super_name 417 super_interface = super_name
408 418
409 interface_name = interface.id 419 interface_name = interface.id
410 auxiliary_file = self._auxiliary_files.get(interface_name) 420 auxiliary_file = self._auxiliary_files.get(interface_name)
411 if auxiliary_file is not None: 421 if auxiliary_file is not None:
412 _logger.info('Skipping %s because %s exists' % ( 422 _logger.info('Skipping %s because %s exists' % (
413 interface_name, auxiliary_file)) 423 interface_name, auxiliary_file))
414 continue 424 continue
415 425
416 426
417 info = self._RecognizeCallback(interface) 427 info = self._RecognizeCallback(interface)
418 if info: 428 if info:
419 self._ProcessCallback(interface, info) 429 for system in self._systems:
430 system.ProcessCallback(interface, info)
420 else: 431 else:
421 if 'Callback' in interface.ext_attrs: 432 if 'Callback' in interface.ext_attrs:
422 _logger.info('Malformed callback: %s' % interface.id) 433 _logger.info('Malformed callback: %s' % interface.id)
423 self._ProcessInterface(interface, super_interface, 434 self._ProcessInterface(interface, super_interface,
424 source_filter, common_prefix) 435 source_filter, common_prefix)
425 processed_interfaces.append(interface)
426 436
427 # Libraries 437 # Libraries
428 if lib_dir: 438 if lib_dir:
429 # New version: Wrapping implementation combined interface and 439 for system in self._systems:
430 # implementation library. 440 system.GenerateLibraries(lib_dir)
431 self.GenerateLibFile('template_wrapping_dom.darttemplate',
432 os.path.join(lib_dir, 'wrapping_dom.dart'),
433 (self._dart_interface_file_paths +
434 self._dart_callback_file_paths +
435 # FIXME: Move the implementation to a separate
436 # library.
437 self._dart_wrapping_file_paths))
438 441
439 # New version: Frog 442 for system in self._systems:
440 self.GenerateLibFile('template_frog_dom.darttemplate', 443 system.Finish()
441 os.path.join(lib_dir, 'dom_frog.dart'),
442 self._dart_frog_file_paths +
443 self._dart_callback_file_paths)
444
445
446 # JavaScript externs files
447 self._GenerateJavaScriptExternsWrapping(database, output_dir)
448 444
449 445
450 def _RecognizeCallback(self, interface): 446 def _RecognizeCallback(self, interface):
451 """Returns the info for the callback method if the interface smells like a 447 """Returns the info for the callback method if the interface smells like a
452 callback. 448 callback.
453 """ 449 """
454 if 'Callback' not in interface.ext_attrs: return None 450 if 'Callback' not in interface.ext_attrs: return None
455 handlers = [op for op in interface.operations if op.id == 'handleEvent'] 451 handlers = [op for op in interface.operations if op.id == 'handleEvent']
456 if not handlers: return None 452 if not handlers: return None
457 if not (handlers == interface.operations): return None 453 if not (handlers == interface.operations): return None
458 return self._AnalyzeOperation(interface, handlers) 454 return self._AnalyzeOperation(interface, handlers)
459 455
460 def _ProcessCallback(self, interface, info):
461 """Generates a typedef for the callback interface."""
462 interface_name = interface.id
463 file_path = self.FilePathForDartInterface(interface_name)
464 self._dart_callback_file_paths.append(file_path)
465 code = self._emitters.FileEmitter(file_path)
466
467 template_file = 'template_callback.darttemplate'
468 code.Emit(''.join(open(template_file).readlines()))
469 code.Emit('typedef $TYPE $NAME($ARGS);\n',
470 NAME=interface.id,
471 TYPE=info.type_name,
472 ARGS=info.arg_implementation_declaration)
473
474 456
475 def _ProcessInterface(self, interface, super_interface_name, 457 def _ProcessInterface(self, interface, super_interface_name,
476 source_filter, 458 source_filter,
477 common_prefix): 459 common_prefix):
478 """.""" 460 """."""
479 _logger.info('Generating %s' % interface.id) 461 _logger.info('Generating %s' % interface.id)
480 462
481 dart_interface_generator = self._MakeDartInterfaceGenerator( 463 generators = [system.InterfaceGenerator(interface,
482 interface, 464 common_prefix,
483 common_prefix, 465 super_interface_name,
484 super_interface_name, 466 source_filter)
485 source_filter) 467 for system in self._systems]
486
487 wrapping_interface_generator = self._MakeWrappingImplInterfaceGenerator(
488 interface,
489 common_prefix,
490 super_interface_name,
491 source_filter)
492
493 frog_interface_generator = self._MakeFrogImplInterfaceGenerator(
494 interface,
495 common_prefix,
496 super_interface_name,
497 source_filter)
498
499 generators = [dart_interface_generator,
500 wrapping_interface_generator,
501 frog_interface_generator]
502 468
503 for generator in generators: 469 for generator in generators:
504 generator.StartInterface() 470 generator.StartInterface()
505 471
506 for const in sorted(interface.constants, ConstantOutputOrder): 472 for const in sorted(interface.constants, ConstantOutputOrder):
507 for generator in generators: 473 for generator in generators:
508 generator.AddConstant(const) 474 generator.AddConstant(const)
509 475
510 for attr in sorted(interface.attributes, AttributeOutputOrder): 476 for attr in sorted(interface.attributes, AttributeOutputOrder):
511 if attr.type.id == 'EventListener': 477 if attr.type.id == 'EventListener':
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 """Returns the file path of the Dart wrapping implementation.""" 690 """Returns the file path of the Dart wrapping implementation."""
725 return os.path.join(self._output_dir, 'src', 'wrapping', 691 return os.path.join(self._output_dir, 'src', 'wrapping',
726 '_%sWrappingImplementation.dart' % interface_name) 692 '_%sWrappingImplementation.dart' % interface_name)
727 693
728 def FilePathForFrogImpl(self, interface_name): 694 def FilePathForFrogImpl(self, interface_name):
729 """Returns the file path of the Frog implementation.""" 695 """Returns the file path of the Frog implementation."""
730 return os.path.join(self._output_dir, 'src', 'frog', 696 return os.path.join(self._output_dir, 'src', 'frog',
731 '%s.dart' % interface_name) 697 '%s.dart' % interface_name)
732 698
733 699
734 def _StartGenerateInterfaceLibrary(self):
735 """."""
736 self._dart_interface_file_paths = []
737 self._dart_wrapping_file_paths = []
738 self._dart_frog_file_paths = []
739
740
741 def _MakeDartInterfaceGenerator(self,
742 interface,
743 common_prefix,
744 super_interface_name,
745 source_filter):
746 """."""
747 interface_name = interface.id
748 dart_interface_file_path = self.FilePathForDartInterface(interface_name)
749
750 self._dart_interface_file_paths.append(dart_interface_file_path)
751
752 dart_interface_code = self._emitters.FileEmitter(dart_interface_file_path)
753
754 template_file = 'template_interface_%s.darttemplate' % interface_name
755 if not os.path.exists(template_file):
756 template_file = 'template_interface.darttemplate'
757 template = ''.join(open(template_file).readlines())
758
759 return DartInterfaceGenerator(
760 interface, dart_interface_code,
761 template,
762 common_prefix, super_interface_name,
763 source_filter)
764
765
766 def _StartGenerateWrappingImpl(self, output_dir):
767 """Prepared for generating wrapping implementation.
768
769 - Creates emitter for JS code.
770 - Creates emitter for Dart code.
771 """
772 js_file_name = os.path.join(output_dir, 'wrapping_dom.js')
773 code = self._emitters.FileEmitter(js_file_name)
774 template = ''.join(open('template_wrapping_dom.js').readlines())
775 (self._wrapping_js_natives,
776 self._wrapping_map) = code.Emit(template)
777
778 _logger.info('Started Generating %s' % js_file_name)
779
780 # Set of (interface, name, kind), kind is 'attribute' or 'operation'.
781 self._wrapping_externs = set()
782
783
784 def _MakeWrappingImplInterfaceGenerator(self,
785 interface,
786 common_prefix,
787 super_interface_name,
788 source_filter):
789 """."""
790 interface_name = interface.id
791 dart_wrapping_file_path = self.FilePathForDartWrappingImpl(interface_name)
792
793 self._dart_wrapping_file_paths.append(dart_wrapping_file_path)
794
795 dart_code = self._emitters.FileEmitter(dart_wrapping_file_path)
796 dart_code.Emit(
797 ''.join(open('template_wrapping_impl.darttemplate').readlines()))
798 return WrappingInterfaceGenerator(interface, super_interface_name,
799 dart_code, self._wrapping_js_natives,
800 self._wrapping_map,
801 self._wrapping_externs,
802 self._BaseDefines(interface))
803
804 def _BaseDefines(self, interface):
805 """Returns a set of names (strings) for members defined in a base class.
806 """
807 def WalkParentChain(interface):
808 if interface.parents:
809 # Only consider primary parent, secondary parents are not on the
810 # implementation class inheritance chain.
811 parent = interface.parents[0]
812 if _IsDartCollectionType(parent.type.id):
813 return
814 if self._database.HasInterface(parent.type.id):
815 parent_interface = self._database.GetInterface(parent.type.id)
816 for attr in parent_interface.attributes:
817 result.add(attr.id)
818 for op in parent_interface.operations:
819 result.add(op.id)
820 WalkParentChain(parent_interface)
821
822 result = set()
823 WalkParentChain(interface)
824 return result;
825
826
827 def _StartGenerateFrogImpl(self, output_dir):
828 """Prepared for generating frog implementation.
829 """
830 self._interface_names_with_subtypes = set()
831 for interface in self._database.GetInterfaces():
832 for parent in interface.parents:
833 self._interface_names_with_subtypes.add(parent.type.id)
834
835 def _MakeFrogImplInterfaceGenerator(self,
836 interface,
837 common_prefix,
838 super_interface_name,
839 source_filter):
840 """."""
841 interface_name = interface.id
842 dart_frog_file_path = self.FilePathForFrogImpl(interface_name)
843
844 self._dart_frog_file_paths.append(dart_frog_file_path)
845
846 dart_code = self._emitters.FileEmitter(dart_frog_file_path)
847 dart_code.Emit(
848 ''.join(open('template_frog_impl.darttemplate').readlines()))
849 return FrogInterfaceGenerator(interface, super_interface_name,
850 self._interface_names_with_subtypes,
851 dart_code)
852
853
854 def _ComputeInheritanceClosure(self): 700 def _ComputeInheritanceClosure(self):
855 def Collect(interface, seen, collected): 701 def Collect(interface, seen, collected):
856 name = interface.id 702 name = interface.id
857 if '<' in name: 703 if '<' in name:
858 # TODO(sra): Handle parameterized types. 704 # TODO(sra): Handle parameterized types.
859 return 705 return
860 if not name in seen: 706 if not name in seen:
861 seen.add(name) 707 seen.add(name)
862 collected.append(name) 708 collected.append(name)
863 for parent in interface.parents: 709 for parent in interface.parents:
864 # TODO(sra): Handle parameterized types. 710 # TODO(sra): Handle parameterized types.
865 if not '<' in parent.type.id: 711 if not '<' in parent.type.id:
866 if self._database.HasInterface(parent.type.id): 712 if self._database.HasInterface(parent.type.id):
867 Collect(self._database.GetInterface(parent.type.id), 713 Collect(self._database.GetInterface(parent.type.id),
868 seen, collected) 714 seen, collected)
869 715
870 self._inheritance_closure = {} 716 self._inheritance_closure = {}
871 for interface in self._database.GetInterfaces(): 717 for interface in self._database.GetInterfaces():
872 seen = set() 718 seen = set()
873 collected = [] 719 collected = []
874 Collect(interface, seen, collected) 720 Collect(interface, seen, collected)
875 self._inheritance_closure[interface.id] = collected 721 self._inheritance_closure[interface.id] = collected
876 722
877 def _AllImplementedInterfaces(self, interface): 723 def _AllImplementedInterfaces(self, interface):
878 """Returns a list of the names of all interfaces implemented by 'interface'. 724 """Returns a list of the names of all interfaces implemented by 'interface'.
879 List includes the name of 'interface'. 725 List includes the name of 'interface'.
880 """ 726 """
881 return self._inheritance_closure[interface.id] 727 return self._inheritance_closure[interface.id]
882 728
883 def _GenerateProtoMap(self):
884 """Determine which DOM type prototypes can be obtained
885 from window properties.
886 """
887 window = None
888 for interface in self._database.GetInterfaces():
889 if interface.id == 'DOMWindow':
890 window = interface
891 prototype_table = {}
892 boring_type_ids = set(['bool', 'int', 'Number', 'String'])
893 if window:
894 for attr in window.attributes:
895 if attr.is_fc_getter:
896 if attr.type.id not in boring_type_ids:
897 prototype_table[attr.type.id] = [attr.id]
898
899 # Manual fixups
900 prototype_table['EventListener'] = ['onload'] # avoid webkit specific.
901 prototype_table['PerformanceMemoryInfo'] = ['performance', 'memory']
902 prototype_table['PerformanceNavigation'] = ['performance', 'navigation']
903 prototype_table['PerformanceTiming'] = ['performance', 'timing']
904
905 return prototype_table
906
907 def _GenerateJavaScriptExternsWrapping(self, database, output_dir):
908 """Generates a JavaScript externs file.
909
910 Generates an externs file that is consistent with generated JavaScript code
911 and Dart APIs for the wrapping implementation.
912 """
913 externs_file_name = os.path.join(output_dir, 'wrapping_dom_externs.js')
914 code = self._emitters.FileEmitter(externs_file_name)
915 _logger.info('Started generating %s' % externs_file_name)
916
917 template = ''.join(open('template_wrapping_dom_externs.js').readlines())
918 namespace = 'dom_externs'
919 members = code.Emit(template, NAMESPACE=namespace)
920
921 # TODO: Filter out externs that are known to the JavaScript back-end. Some
922 # of the known externs have useful declarations like @nosideeffects that
923 # might improve back-end analysis.
924
925 names = dict() # maps name to (interface, kind)
926 for (interface, name, kind) in self._wrapping_externs:
927 if name not in _javascript_keywords:
928 if name not in names:
929 names[name] = set()
930 names[name].add((interface, kind))
931
932 for name in sorted(names.keys()):
933 # Simply export the property name.
934 extern = emitter.Format('$NAMESPACE.$NAME;',
935 NAMESPACE=namespace, NAME=name)
936 members.EmitRaw(extern)
937 # Add a big comment of all the attributes and operations contributing to
938 # the export.
939 filler = ' ' * (40 - 2 - len(extern)) # '2' for 2 spaces before comment.
940 separator = filler + ' //'
941 for (interface, kind) in sorted(names[name]):
942 members.Emit('$SEP $KIND $INTERFACE.$NAME',
943 NAME=name, INTERFACE=interface, KIND=kind, SEP=separator)
944 separator = ','
945 members.Emit('\n')
946 729
947 730
948 def _GenerateJavaScriptExternInterfaces(self, 731 def _GenerateJavaScriptExternInterfaces(self,
949 database, 732 database,
950 namespace, 733 namespace,
951 window_code, 734 window_code,
952 prop_code): 735 prop_code):
953 """Generate externs for JavaScript patch code. 736 """Generate externs for JavaScript patch code.
954 """ 737 """
955 738
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 """Format lines of text with indent.""" 840 """Format lines of text with indent."""
1058 def FormatLine(line): 841 def FormatLine(line):
1059 if line.strip(): 842 if line.strip():
1060 return '%s%s\n' % (indent, line) 843 return '%s%s\n' % (indent, line)
1061 else: 844 else:
1062 return '\n' 845 return '\n'
1063 return ''.join(FormatLine(line) for line in text.split('\n')) 846 return ''.join(FormatLine(line) for line in text.split('\n'))
1064 847
1065 # ------------------------------------------------------------------------------ 848 # ------------------------------------------------------------------------------
1066 849
850 class System(object):
851 """Generates all the files for one implementation."""
852
853 def __init__(self, database, emitters, output_dir):
854 self._database = database
855 self._emitters = emitters
856 self._output_dir = output_dir
857 self._dart_callback_file_paths = []
858
859 def InterfaceGenerator(self,
860 interface,
861 common_prefix,
862 super_interface_name,
863 source_filter):
864 """Returns an interface generator for |interface|."""
865 return None
866
867 def ProcessCallback(self, interface, info):
868 pass
869
870 def GenerateLibraries(self, lib_dir):
871 pass
872
873 def Finish(self):
874 pass
875
876
877 def _ProcessCallback(self, interface, info, file_path):
878 """Generates a typedef for the callback interface."""
879 self._dart_callback_file_paths.append(file_path)
880 code = self._emitters.FileEmitter(file_path)
881
882 template_file = 'template_callback.darttemplate'
883 code.Emit(''.join(open(template_file).readlines()))
884 code.Emit('typedef $TYPE $NAME($ARGS);\n',
885 NAME=interface.id,
886 TYPE=info.type_name,
887 ARGS=info.arg_implementation_declaration)
888
889 def _GenerateLibFile(self, lib_template, lib_file_path, file_paths):
890 """Generates a lib file from a template and a list of files."""
891 # Load template.
892 template = ''.join(open(lib_template).readlines())
893 # Generate the .lib file.
894 lib_file_contents = self._emitters.FileEmitter(lib_file_path)
895
896 # Emit the list of #source directives.
897 list_emitter = lib_file_contents.Emit(template)
898 lib_file_dir = os.path.dirname(lib_file_path)
899 for path in sorted(file_paths):
900 relpath = os.path.relpath(path, lib_file_dir)
901 list_emitter.Emit("#source('$PATH');\n", PATH=relpath)
902
903
904 def _BaseDefines(self, interface):
905 """Returns a set of names (strings) for members defined in a base class.
906 """
907 def WalkParentChain(interface):
908 if interface.parents:
909 # Only consider primary parent, secondary parents are not on the
910 # implementation class inheritance chain.
911 parent = interface.parents[0]
912 if _IsDartCollectionType(parent.type.id):
913 return
914 if self._database.HasInterface(parent.type.id):
915 parent_interface = self._database.GetInterface(parent.type.id)
916 for attr in parent_interface.attributes:
917 result.add(attr.id)
918 for op in parent_interface.operations:
919 result.add(op.id)
920 WalkParentChain(parent_interface)
921
922 result = set()
923 WalkParentChain(interface)
924 return result;
925
926
927 # ------------------------------------------------------------------------------
928
929 class WrappingInterfacesSystem(System):
930
931 def __init__(self, database, emitters, output_dir):
932 super(WrappingInterfacesSystem, self).__init__(
933 database, emitters, output_dir)
934 self._dart_interface_file_paths = []
935
936
937 def InterfaceGenerator(self,
938 interface,
939 common_prefix,
940 super_interface_name,
941 source_filter):
942 """."""
943 interface_name = interface.id
944 dart_interface_file_path = self._FilePathForDartInterface(interface_name)
945
946 self._dart_interface_file_paths.append(dart_interface_file_path)
947
948 dart_interface_code = self._emitters.FileEmitter(dart_interface_file_path)
949
950 template_file = 'template_interface_%s.darttemplate' % interface_name
951 if not os.path.exists(template_file):
952 template_file = 'template_interface.darttemplate'
953 template = ''.join(open(template_file).readlines())
954
955 return DartInterfaceGenerator(
956 interface, dart_interface_code,
957 template,
958 common_prefix, super_interface_name,
959 source_filter)
960
961 def ProcessCallback(self, interface, info):
962 """Generates a typedef for the callback interface."""
963 interface_name = interface.id
964 file_path = self._FilePathForDartInterface(interface_name)
965 self._ProcessCallback(interface, info, file_path)
966
967 def GenerateLibraries(self, lib_dir):
968 # Library generated for implementation.
969 self._GenerateLibFile(
970 'template_wrapping_dom.darttemplate',
971 os.path.join(lib_dir, 'wrapping_dom.dart'),
972 (self._dart_interface_file_paths +
973 self._dart_callback_file_paths +
974 # FIXME: Move the implementation to a separate
975 # library.
976 self._implementation_system._dart_wrapping_file_paths
977 ))
978
979
980 def _FilePathForDartInterface(self, interface_name):
981 """Returns the file path of the Dart interface definition."""
982 return os.path.join(self._output_dir, 'src', 'interface',
983 '%s.dart' % interface_name)
984
985
986 # ------------------------------------------------------------------------------
987
988 class WrappingImplementationSystem(System):
989
990 def __init__(self, database, emitters, output_dir):
991 """Prepared for generating wrapping implementation.
992
993 - Creates emitter for JS code.
994 - Creates emitter for Dart code.
995 """
996 super(WrappingImplementationSystem, self).__init__(
997 database, emitters, output_dir)
998 self._dart_wrapping_file_paths = []
999
1000 js_file_name = os.path.join(output_dir, 'wrapping_dom.js')
1001 code = self._emitters.FileEmitter(js_file_name)
1002 template = ''.join(open('template_wrapping_dom.js').readlines())
1003 (self._wrapping_js_natives,
1004 self._wrapping_map) = code.Emit(template)
1005
1006 _logger.info('Started Generating %s' % js_file_name)
1007
1008 # Set of (interface, name, kind), kind is 'attribute' or 'operation'.
1009 self._wrapping_externs = set()
1010
1011
1012 def InterfaceGenerator(self,
1013 interface,
1014 common_prefix,
1015 super_interface_name,
1016 source_filter):
1017 """."""
1018 interface_name = interface.id
1019 dart_wrapping_file_path = self._FilePathForDartWrappingImpl(interface_name)
1020
1021 self._dart_wrapping_file_paths.append(dart_wrapping_file_path)
1022
1023 dart_code = self._emitters.FileEmitter(dart_wrapping_file_path)
1024 dart_code.Emit(
1025 ''.join(open('template_wrapping_impl.darttemplate').readlines()))
1026 return WrappingInterfaceGenerator(interface, super_interface_name,
1027 dart_code, self._wrapping_js_natives,
1028 self._wrapping_map,
1029 self._wrapping_externs,
1030 self._BaseDefines(interface))
1031
1032 def ProcessCallback(self, interface, info):
1033 pass
1034
1035 def GenerateLibraries(self, lib_dir):
1036 pass
1037
1038 def Finish(self):
1039 self._GenerateJavaScriptExternsWrapping(self._database, self._output_dir)
1040
1041
1042 def _FilePathForDartWrappingImpl(self, interface_name):
1043 """Returns the file path of the Dart wrapping implementation."""
1044 return os.path.join(self._output_dir, 'src', 'wrapping',
1045 '_%sWrappingImplementation.dart' % interface_name)
1046
1047 def _GenerateJavaScriptExternsWrapping(self, database, output_dir):
1048 """Generates a JavaScript externs file.
1049
1050 Generates an externs file that is consistent with generated JavaScript code
1051 and Dart APIs for the wrapping implementation.
1052 """
1053 externs_file_name = os.path.join(output_dir, 'wrapping_dom_externs.js')
1054 code = self._emitters.FileEmitter(externs_file_name)
1055 _logger.info('Started generating %s' % externs_file_name)
1056
1057 template = ''.join(open('template_wrapping_dom_externs.js').readlines())
1058 namespace = 'dom_externs'
1059 members = code.Emit(template, NAMESPACE=namespace)
1060
1061 # TODO: Filter out externs that are known to the JavaScript back-end. Some
1062 # of the known externs have useful declarations like @nosideeffects that
1063 # might improve back-end analysis.
1064
1065 names = dict() # maps name to (interface, kind)
1066 for (interface, name, kind) in self._wrapping_externs:
1067 if name not in _javascript_keywords:
1068 if name not in names:
1069 names[name] = set()
1070 names[name].add((interface, kind))
1071
1072 for name in sorted(names.keys()):
1073 # Simply export the property name.
1074 extern = emitter.Format('$NAMESPACE.$NAME;',
1075 NAMESPACE=namespace, NAME=name)
1076 members.EmitRaw(extern)
1077 # Add a big comment of all the attributes and operations contributing to
1078 # the export.
1079 filler = ' ' * (40 - 2 - len(extern)) # '2' for 2 spaces before comment.
1080 separator = filler + ' //'
1081 for (interface, kind) in sorted(names[name]):
1082 members.Emit('$SEP $KIND $INTERFACE.$NAME',
1083 NAME=name, INTERFACE=interface, KIND=kind, SEP=separator)
1084 separator = ','
1085 members.Emit('\n')
1086
1087 # ------------------------------------------------------------------------------
1088
1089 class FrogSystem(System):
1090
1091 def __init__(self, database, emitters, output_dir):
1092 super(FrogSystem, self).__init__(database, emitters, output_dir)
1093 self._dart_frog_file_paths = []
1094
1095 def InterfaceGenerator(self,
1096 interface,
1097 common_prefix,
1098 super_interface_name,
1099 source_filter):
1100 """."""
1101 dart_frog_file_path = self._FilePathForFrogImpl(interface.id)
1102
1103 self._dart_frog_file_paths.append(dart_frog_file_path)
1104
1105 dart_code = self._emitters.FileEmitter(dart_frog_file_path)
1106 dart_code.Emit(
1107 ''.join(open('template_frog_impl.darttemplate').readlines()))
1108 return FrogInterfaceGenerator(interface, super_interface_name,
1109 dart_code)
1110
1111 def ProcessCallback(self, interface, info):
1112 """Generates a typedef for the callback interface."""
1113 file_path = self._FilePathForFrogImpl(interface.id)
1114 self._ProcessCallback(interface, info, file_path)
1115
1116 def GenerateLibraries(self, lib_dir):
1117 self._GenerateLibFile(
1118 'template_frog_dom.darttemplate',
1119 os.path.join(lib_dir, 'dom_frog.dart'),
1120 self._dart_frog_file_paths +
1121 self._dart_callback_file_paths)
1122
1123 def Finish(self):
1124 pass
1125
1126 def _FilePathForFrogImpl(self, interface_name):
1127 """Returns the file path of the Frog implementation."""
1128 return os.path.join(self._output_dir, 'src', 'frog',
1129 '%s.dart' % interface_name)
1130
1131
1132 # ------------------------------------------------------------------------------
1133
1067 class DartInterfaceGenerator(object): 1134 class DartInterfaceGenerator(object):
1068 """Generates Dart Interface definition for one DOM IDL interface.""" 1135 """Generates Dart Interface definition for one DOM IDL interface."""
1069 1136
1070 def __init__(self, interface, emitter, template, 1137 def __init__(self, interface, emitter, template,
1071 common_prefix, super_interface, source_filter): 1138 common_prefix, super_interface, source_filter):
1072 """Generates Dart code for the given interface. 1139 """Generates Dart code for the given interface.
1073 1140
1074 Args: 1141 Args:
1075 interface -- an IDLInterface instance. It is assumed that all types have 1142 interface -- an IDLInterface instance. It is assumed that all types have
1076 been converted to Dart types (e.g. int, String), unless they are in the 1143 been converted to Dart types (e.g. int, String), unless they are in the
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after
1740 self.GenerateDispatch( 1807 self.GenerateDispatch(
1741 true_code, info, indent + ' ', position + 1, positive) 1808 true_code, info, indent + ' ', position + 1, positive)
1742 return True 1809 return True
1743 1810
1744 1811
1745 # ------------------------------------------------------------------------------ 1812 # ------------------------------------------------------------------------------
1746 1813
1747 class FrogInterfaceGenerator(object): 1814 class FrogInterfaceGenerator(object):
1748 """Generates a Frog class for a DOM IDL interface.""" 1815 """Generates a Frog class for a DOM IDL interface."""
1749 1816
1750 def __init__(self, interface, super_interface, interfaces_with_subtypes, 1817 def __init__(self, interface, super_interface, dart_code):
1751 dart_code):
1752 """Generates Dart code for the given interface. 1818 """Generates Dart code for the given interface.
1753 1819
1754 Args: 1820 Args:
1755 1821
1756 interface: an IDLInterface instance. It is assumed that all types have 1822 interface: an IDLInterface instance. It is assumed that all types have
1757 been converted to Dart types (e.g. int, String), unless they are in 1823 been converted to Dart types (e.g. int, String), unless they are in
1758 the same package as the interface. 1824 the same package as the interface.
1759 super_interface: A string or None, the name of the common interface that 1825 super_interface: A string or None, the name of the common interface that
1760 this interface implements, if any. 1826 this interface implements, if any.
1761 interfaces_with_subtypes: A set of strings names of interfaces that have
1762 at least one subtype.
1763 dart_code: an Emitter for the file containing the Dart implementation 1827 dart_code: an Emitter for the file containing the Dart implementation
1764 class. 1828 class.
1765 """ 1829 """
1766 self._interface = interface 1830 self._interface = interface
1767 self._super_interface = super_interface 1831 self._super_interface = super_interface
1768 self._interfaces_with_subtypes = interfaces_with_subtypes
1769 self._dart_code = dart_code 1832 self._dart_code = dart_code
1770 self._current_secondary_parent = None 1833 self._current_secondary_parent = None
1771 1834
1772 1835
1773 def StartInterface(self): 1836 def StartInterface(self):
1774 interface = self._interface 1837 interface = self._interface
1775 interface_name = interface.id 1838 interface_name = interface.id
1776 1839
1777 self._class_name = self._ImplClassName(interface_name) 1840 self._class_name = self._ImplClassName(interface_name)
1778 1841
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
1952 Arguments: 2015 Arguments:
1953 info: An OperationInfo object. 2016 info: An OperationInfo object.
1954 """ 2017 """
1955 # TODO(vsm): Handle overloads. 2018 # TODO(vsm): Handle overloads.
1956 self._members_emitter.Emit( 2019 self._members_emitter.Emit(
1957 '\n' 2020 '\n'
1958 ' $TYPE $NAME($ARGS) native;\n', 2021 ' $TYPE $NAME($ARGS) native;\n',
1959 TYPE=info.type_name, 2022 TYPE=info.type_name,
1960 NAME=info.name, 2023 NAME=info.name,
1961 ARGS=info.arg_implementation_declaration) 2024 ARGS=info.arg_implementation_declaration)
OLDNEW
« no previous file with comments | « client/dom/generated/src/wrapping/_StorageWrappingImplementation.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698