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

Side by Side Diff: tools/dom/scripts/databasebuilder.py

Issue 1001983003: Added --examine to produce analysis of IDL files (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Changed is_dictionary to check_dictionaries Created 5 years, 9 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 | « tools/dom/scripts/database.py ('k') | tools/dom/scripts/fremontcutbuilder.py » ('j') | 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 import copy 6 import copy
7 import database 7 import database
8 import logging 8 import logging
9 import monitored 9 import monitored
10 import multiprocessing 10 import multiprocessing
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 def dictionary_to_map(type_node): 746 def dictionary_to_map(type_node):
747 if self._database.HasDictionary(type_node.id): 747 if self._database.HasDictionary(type_node.id):
748 type_node.dictionary = type_node.id 748 type_node.dictionary = type_node.id
749 type_node.id = 'Dictionary' 749 type_node.id = 'Dictionary'
750 750
751 def all_types(node): 751 def all_types(node):
752 map(dictionary_to_map, node.all(IDLType)) 752 map(dictionary_to_map, node.all(IDLType))
753 753
754 for interface in self._database.GetInterfaces(): 754 for interface in self._database.GetInterfaces():
755 map(all_types, interface.all(IDLExtAttrFunctionValue)) 755 map(all_types, interface.all(IDLExtAttrFunctionValue))
756 map(all_types, interface.attributes)
756 map(all_types, interface.operations) 757 map(all_types, interface.operations)
757 758
758 def fetch_constructor_data(self, options): 759 def fetch_constructor_data(self, options):
759 window_interface = self._database.GetInterface('Window') 760 window_interface = self._database.GetInterface('Window')
760 for attr in window_interface.attributes: 761 for attr in window_interface.attributes:
761 type = attr.type.id 762 type = attr.type.id
762 if not type.endswith('Constructor'): 763 if not type.endswith('Constructor'):
763 continue 764 continue
764 type = re.sub('(Constructor)+$', '', type) 765 type = re.sub('(Constructor)+$', '', type)
765 # TODO(antonm): Ideally we'd like to have pristine copy of WebKit IDLs and fetch 766 # TODO(antonm): Ideally we'd like to have pristine copy of WebKit IDLs and fetch
766 # this information directly from it. Unfortunately right now database is massaged 767 # this information directly from it. Unfortunately right now database is massaged
767 # a lot so it's difficult to maintain necessary information on Window itse lf. 768 # a lot so it's difficult to maintain necessary information on Window itse lf.
768 interface = self._database.GetInterface(type) 769 interface = self._database.GetInterface(type)
769 if 'V8EnabledPerContext' in attr.ext_attrs: 770 if 'V8EnabledPerContext' in attr.ext_attrs:
770 interface.ext_attrs['synthesizedV8EnabledPerContext'] = \ 771 interface.ext_attrs['synthesizedV8EnabledPerContext'] = \
771 attr.ext_attrs['V8EnabledPerContext'] 772 attr.ext_attrs['V8EnabledPerContext']
772 if 'V8EnabledAtRuntime' in attr.ext_attrs: 773 if 'V8EnabledAtRuntime' in attr.ext_attrs:
773 interface.ext_attrs['synthesizedV8EnabledAtRuntime'] = \ 774 interface.ext_attrs['synthesizedV8EnabledAtRuntime'] = \
774 attr.ext_attrs['V8EnabledAtRuntime'] or attr.id 775 attr.ext_attrs['V8EnabledAtRuntime'] or attr.id
776
777 # Iterate of the database looking for relationships between dictionaries and
778 # interfaces marked with NoInterfaceObject. This mechanism can be used for
779 # other IDL analysis.
780 def examine_database(self):
781 # Contains list of dictionary structure: {'dictionary': dictionary, 'usages' : []}
782 self._diag_dictionaries = [];
783 self._dictionaries_used_types = [];
784
785 # Record any dictionary.
786 for dictionary in self._database.GetDictionaries():
787 self._diag_dictionaries.append({'dictionary': dictionary, 'usages': []});
788
789 # Contains list of NoInterfaceObject structures: {'no_interface_object': dic tionary, 'usages': []}
790 self._diag_no_interfaces = [];
791 self._no_interfaces_used_types = [];
792
793 # Record any interface with Blink IDL Extended Attribute 'NoInterfaceObject' .
794 for interface in self._database.GetInterfaces():
795 if interface.is_no_interface_object:
796 self._diag_no_interfaces.append({'no_interface_object': interface, 'usag es': []});
797
798 for interface in self._database.GetInterfaces():
799 self._constructors(interface)
800 self._constructors(interface, check_dictionaries=False)
801
802 for attribute in interface.attributes:
803 self._attribute_operation(interface, attribute)
804 self._attribute_operation(interface, attribute, check_dictionaries=False )
805
806 for operation in interface.operations:
807 self._attribute_operation(interface, operation)
808 self._attribute_operation(interface, operation, check_dictionaries=False )
809
810 # Report all dictionaries and their usage.
811 self._output_examination()
812 # Report all interface marked with NoInterfaceObject and their usage.
813 self._output_examination(check_dictionaries=False)
814
815 print '\nKey:'
816 print ' (READ-ONLY) - read-only attribute has relationship'
817 print ' (GET/SET) - attribute has relationship'
818 print ' RETURN - operation\'s returned value has relationship'
819 print ' (ARGUMENT) - operation\'s argument(s) has relationship'
820
821 print '\n\nExamination Complete\n'
822
823 def _output_examination(self, check_dictionaries=True):
824 # Output diagnostics. First columns is Dictionary or NoInterfaceObject e.g.,
825 # | Dictionary | Used In Interface | Usage Operation/Attribute |
826 print '\n\n'
827 title_bar = ['Dictionary', 'Used In Interface', 'Usage Operation/Attribute'] if check_dictionaries \
828 else ['NoInterfaceObject', 'Used In Interface', 'Usage Operation /Attribute']
829 self._tabulate_title(title_bar)
830 diags = self._diag_dictionaries if check_dictionaries else self._diag_no_int erfaces
831 for diag in diags:
832 self._tabluate([diag['dictionary' if check_dictionaries else 'no_interface _object'].id, '', ''])
833 for usage in diag['usages']:
834 detail = ''
835 if 'attribute' in usage:
836 attribute_type = 'READ-ONLY' if not usage['argument'] else 'GET/SET'
837 detail = '(%s) %s' % (attribute_type, usage['attribute'])
838 elif 'operation' in usage:
839 detail = '%s %s%s' % ('RETURN' if usage['result'] else '',
840 usage['operation'],
841 '(ARGUMENT)' if usage['argument'] else '')
842 self._tabluate([None, usage['interface'], detail])
843 self._tabulate_break()
844
845 # operation_or_attribute either IDLOperation or IDLAttribute if None then
846 # its a constructor (IDLExtAttrFunctionValue).
847 def _mark_usage(self, interface, operation_or_attribute = None, check_dictiona ries=True):
848 for diag in self._diag_dictionaries if check_dictionaries else self._diag_no _interfaces:
849 for usage in diag['usages']:
850 if not usage['interface']:
851 usage['interface'] = interface.id
852 if isinstance(operation_or_attribute, IDLOperation):
853 usage['operation'] = operation_or_attribute.id
854 if check_dictionaries:
855 usage['result'] = hasattr(operation_or_attribute.type, 'dictionary ') and \
856 operation_or_attribute.type.dictionary == diag['dictionary'].id
857 else:
858 usage['result'] = operation_or_attribute.type.id == diag['no_inter face_object'].id
859 usage['argument'] = False
860 for argument in operation_or_attribute.arguments:
861 if check_dictionaries:
862 arg = hasattr(argument.type, 'dictionary') and argument.type.dic tionary == diag['dictionary'].id
863 else:
864 arg = argument.type.id == diag['no_interface_object'].id
865 if arg:
866 usage['argument'] = arg
867 elif isinstance(operation_or_attribute, IDLAttribute):
868 usage['attribute'] = operation_or_attribute.id
869 usage['result'] = True
870 usage['argument'] = not operation_or_attribute.is_read_only
871 elif not operation_or_attribute:
872 # Its a constructor only argument is dictionary or interface with No InterfaceObject.
873 usage['operation'] = 'constructor'
874 usage['result'] = False
875 usage['argument'] = True
876
877 def _remember_usage(self, node, check_dictionaries=True):
878 if check_dictionaries:
879 used_types = self._dictionaries_used_types
880 diag_list = self._diag_dictionaries
881 diag_name = 'dictionary'
882 else:
883 used_types = self._no_interfaces_used_types
884 diag_list = self._diag_no_interfaces
885 diag_name = 'no_interface_object'
886
887 if len(used_types) > 0:
888 normalized_used = list(set(used_types))
889 for recorded_id in normalized_used:
890 for diag in diag_list:
891 if diag[diag_name].id == recorded_id:
892 diag['usages'].append({'interface': None, 'node': node})
893
894 # Iterator function to look for any IDLType that is a dictionary then remember
895 # that dictionary.
896 def _dictionary_used(self, type_node):
897 if hasattr(type_node, 'dictionary'):
898 dictionary_id = type_node.dictionary
899 if self._database.HasDictionary(dictionary_id):
900 for diag_dictionary in self._diag_dictionaries:
901 if diag_dictionary['dictionary'].id == dictionary_id:
902 # Record the dictionary that was referenced.
903 self._dictionaries_used_types.append(dictionary_id)
904 return
905
906 # If we get to this point, the IDL dictionary was never defined ... oops.
907 print 'DIAGNOSE_ERROR: IDL Dictionary %s doesn\'t exist.' % dictionary_id
908
909 # Iterator function to look for any IDLType that is an interface marked with
910 # NoInterfaceObject then remember that interface.
911 def _no_interface_used(self, type_node):
912 if hasattr(type_node, 'id'):
913 no_interface_id = type_node.id
914 if self._database.HasInterface(no_interface_id):
915 no_interface = self._database.GetInterface(no_interface_id)
916 if no_interface.is_no_interface_object:
917 for diag_no_interface in self._diag_no_interfaces:
918 if diag_no_interface['no_interface_object'].id == no_interface_id:
919 # Record the interface marked with NoInterfaceObject.
920 self._no_interfaces_used_types.append(no_interface_id)
921 return
922
923 def _constructors(self, interface, check_dictionaries=True):
924 if check_dictionaries:
925 self._dictionaries_used_types = []
926 constructor_function = self._dictionary_constructor_types
927 else:
928 self._no_interfaces_used_types = [];
929 constructor_function = self._no_interface_constructor_types
930
931 map(constructor_function, interface.all(IDLExtAttrFunctionValue))
932
933 self._mark_usage(interface, check_dictionaries=check_dictionaries)
934
935 # Scan an attribute or operation for a dictionary or interface with NoInterfac eObject
936 # reference.
937 def _attribute_operation(self, interface, operation_attribute, check_dictionar ies=True):
938 if check_dictionaries:
939 self._dictionaries_used_types = []
940 used = self._dictionary_used
941 else:
942 self._no_interfaces_used_types = [];
943 used = self._no_interface_used
944
945 map(used, operation_attribute.all(IDLType))
946
947 self._remember_usage(operation_attribute, check_dictionaries=check_dictionar ies)
948 self._mark_usage(interface, operation_attribute, check_dictionaries=check_di ctionaries)
949
950 # Iterator function for map to iterate over all constructor types
951 # (IDLExtAttrFunctionValue) that have a dictionary reference.
952 def _dictionary_constructor_types(self, node):
953 self._dictionaries_used_types = []
954 map(self._dictionary_used, node.all(IDLType))
955 self._remember_usage(node)
956
957 # Iterator function for map to iterate over all constructor types
958 # (IDLExtAttrFunctionValue) that reference an interface with NoInterfaceObject .
959 def _no_interface_constructor_types(self, node):
960 self._no_interfaces_used_types = [];
961 map(self._no_interface_used, node.all(IDLType))
962 self._remember_usage(node, check_dictionaries=False)
963
964 # Maximum width of each column.
965 def _TABULATE_WIDTH(self):
966 return 45
967
968 def _tabulate_title(self, row_title):
969 title_separator = "=" * self._TABULATE_WIDTH()
970 self._tabluate([title_separator, title_separator, title_separator])
971 self._tabluate(row_title)
972 self._tabluate([title_separator, title_separator, title_separator])
973
974 def _tabulate_break(self):
975 break_separator = "-" * self._TABULATE_WIDTH()
976 self._tabluate([break_separator, break_separator, break_separator])
977
978 def _tabluate(self, columns):
979 """Tabulate a list of columns for a row. Each item in columns is a column
980 value each column will be padded up to _TABULATE_WIDTH. Each
981 column starts/ends with a vertical bar '|' the format a row:
982
983 | columns[0] | columns[1] | columns[2] | ... |
984 """
985 if len(columns) > 0:
986 for column in columns:
987 value = '' if not column else column
988 sys.stdout.write('|{0:^{1}}'.format(value, self._TABULATE_WIDTH()))
989 else:
990 sys.stdout.write('|{0:^{1}}'.format('', self._TABULATE_WIDTH()))
991
992 sys.stdout.write('|\n')
OLDNEW
« no previous file with comments | « tools/dom/scripts/database.py ('k') | tools/dom/scripts/fremontcutbuilder.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698