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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/dom/scripts/database.py ('k') | tools/dom/scripts/fremontcutbuilder.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/dom/scripts/databasebuilder.py
diff --git a/tools/dom/scripts/databasebuilder.py b/tools/dom/scripts/databasebuilder.py
index 46c82a831bcd166a538adb9e845f44a1760b1a55..458f570ae888ed06fe73aba728d79a56ef0f13c8 100755
--- a/tools/dom/scripts/databasebuilder.py
+++ b/tools/dom/scripts/databasebuilder.py
@@ -753,6 +753,7 @@ class DatabaseBuilder(object):
for interface in self._database.GetInterfaces():
map(all_types, interface.all(IDLExtAttrFunctionValue))
+ map(all_types, interface.attributes)
map(all_types, interface.operations)
def fetch_constructor_data(self, options):
@@ -772,3 +773,220 @@ class DatabaseBuilder(object):
if 'V8EnabledAtRuntime' in attr.ext_attrs:
interface.ext_attrs['synthesizedV8EnabledAtRuntime'] = \
attr.ext_attrs['V8EnabledAtRuntime'] or attr.id
+
+ # Iterate of the database looking for relationships between dictionaries and
+ # interfaces marked with NoInterfaceObject. This mechanism can be used for
+ # other IDL analysis.
+ def examine_database(self):
+ # Contains list of dictionary structure: {'dictionary': dictionary, 'usages': []}
+ self._diag_dictionaries = [];
+ self._dictionaries_used_types = [];
+
+ # Record any dictionary.
+ for dictionary in self._database.GetDictionaries():
+ self._diag_dictionaries.append({'dictionary': dictionary, 'usages': []});
+
+ # Contains list of NoInterfaceObject structures: {'no_interface_object': dictionary, 'usages': []}
+ self._diag_no_interfaces = [];
+ self._no_interfaces_used_types = [];
+
+ # Record any interface with Blink IDL Extended Attribute 'NoInterfaceObject'.
+ for interface in self._database.GetInterfaces():
+ if interface.is_no_interface_object:
+ self._diag_no_interfaces.append({'no_interface_object': interface, 'usages': []});
+
+ for interface in self._database.GetInterfaces():
+ self._constructors(interface)
+ self._constructors(interface, check_dictionaries=False)
+
+ for attribute in interface.attributes:
+ self._attribute_operation(interface, attribute)
+ self._attribute_operation(interface, attribute, check_dictionaries=False)
+
+ for operation in interface.operations:
+ self._attribute_operation(interface, operation)
+ self._attribute_operation(interface, operation, check_dictionaries=False)
+
+ # Report all dictionaries and their usage.
+ self._output_examination()
+ # Report all interface marked with NoInterfaceObject and their usage.
+ self._output_examination(check_dictionaries=False)
+
+ print '\nKey:'
+ print ' (READ-ONLY) - read-only attribute has relationship'
+ print ' (GET/SET) - attribute has relationship'
+ print ' RETURN - operation\'s returned value has relationship'
+ print ' (ARGUMENT) - operation\'s argument(s) has relationship'
+
+ print '\n\nExamination Complete\n'
+
+ def _output_examination(self, check_dictionaries=True):
+ # Output diagnostics. First columns is Dictionary or NoInterfaceObject e.g.,
+ # | Dictionary | Used In Interface | Usage Operation/Attribute |
+ print '\n\n'
+ title_bar = ['Dictionary', 'Used In Interface', 'Usage Operation/Attribute'] if check_dictionaries \
+ else ['NoInterfaceObject', 'Used In Interface', 'Usage Operation/Attribute']
+ self._tabulate_title(title_bar)
+ diags = self._diag_dictionaries if check_dictionaries else self._diag_no_interfaces
+ for diag in diags:
+ self._tabluate([diag['dictionary' if check_dictionaries else 'no_interface_object'].id, '', ''])
+ for usage in diag['usages']:
+ detail = ''
+ if 'attribute' in usage:
+ attribute_type = 'READ-ONLY' if not usage['argument'] else 'GET/SET'
+ detail = '(%s) %s' % (attribute_type, usage['attribute'])
+ elif 'operation' in usage:
+ detail = '%s %s%s' % ('RETURN' if usage['result'] else '',
+ usage['operation'],
+ '(ARGUMENT)' if usage['argument'] else '')
+ self._tabluate([None, usage['interface'], detail])
+ self._tabulate_break()
+
+ # operation_or_attribute either IDLOperation or IDLAttribute if None then
+ # its a constructor (IDLExtAttrFunctionValue).
+ def _mark_usage(self, interface, operation_or_attribute = None, check_dictionaries=True):
+ for diag in self._diag_dictionaries if check_dictionaries else self._diag_no_interfaces:
+ for usage in diag['usages']:
+ if not usage['interface']:
+ usage['interface'] = interface.id
+ if isinstance(operation_or_attribute, IDLOperation):
+ usage['operation'] = operation_or_attribute.id
+ if check_dictionaries:
+ usage['result'] = hasattr(operation_or_attribute.type, 'dictionary') and \
+ operation_or_attribute.type.dictionary == diag['dictionary'].id
+ else:
+ usage['result'] = operation_or_attribute.type.id == diag['no_interface_object'].id
+ usage['argument'] = False
+ for argument in operation_or_attribute.arguments:
+ if check_dictionaries:
+ arg = hasattr(argument.type, 'dictionary') and argument.type.dictionary == diag['dictionary'].id
+ else:
+ arg = argument.type.id == diag['no_interface_object'].id
+ if arg:
+ usage['argument'] = arg
+ elif isinstance(operation_or_attribute, IDLAttribute):
+ usage['attribute'] = operation_or_attribute.id
+ usage['result'] = True
+ usage['argument'] = not operation_or_attribute.is_read_only
+ elif not operation_or_attribute:
+ # Its a constructor only argument is dictionary or interface with NoInterfaceObject.
+ usage['operation'] = 'constructor'
+ usage['result'] = False
+ usage['argument'] = True
+
+ def _remember_usage(self, node, check_dictionaries=True):
+ if check_dictionaries:
+ used_types = self._dictionaries_used_types
+ diag_list = self._diag_dictionaries
+ diag_name = 'dictionary'
+ else:
+ used_types = self._no_interfaces_used_types
+ diag_list = self._diag_no_interfaces
+ diag_name = 'no_interface_object'
+
+ if len(used_types) > 0:
+ normalized_used = list(set(used_types))
+ for recorded_id in normalized_used:
+ for diag in diag_list:
+ if diag[diag_name].id == recorded_id:
+ diag['usages'].append({'interface': None, 'node': node})
+
+ # Iterator function to look for any IDLType that is a dictionary then remember
+ # that dictionary.
+ def _dictionary_used(self, type_node):
+ if hasattr(type_node, 'dictionary'):
+ dictionary_id = type_node.dictionary
+ if self._database.HasDictionary(dictionary_id):
+ for diag_dictionary in self._diag_dictionaries:
+ if diag_dictionary['dictionary'].id == dictionary_id:
+ # Record the dictionary that was referenced.
+ self._dictionaries_used_types.append(dictionary_id)
+ return
+
+ # If we get to this point, the IDL dictionary was never defined ... oops.
+ print 'DIAGNOSE_ERROR: IDL Dictionary %s doesn\'t exist.' % dictionary_id
+
+ # Iterator function to look for any IDLType that is an interface marked with
+ # NoInterfaceObject then remember that interface.
+ def _no_interface_used(self, type_node):
+ if hasattr(type_node, 'id'):
+ no_interface_id = type_node.id
+ if self._database.HasInterface(no_interface_id):
+ no_interface = self._database.GetInterface(no_interface_id)
+ if no_interface.is_no_interface_object:
+ for diag_no_interface in self._diag_no_interfaces:
+ if diag_no_interface['no_interface_object'].id == no_interface_id:
+ # Record the interface marked with NoInterfaceObject.
+ self._no_interfaces_used_types.append(no_interface_id)
+ return
+
+ def _constructors(self, interface, check_dictionaries=True):
+ if check_dictionaries:
+ self._dictionaries_used_types = []
+ constructor_function = self._dictionary_constructor_types
+ else:
+ self._no_interfaces_used_types = [];
+ constructor_function = self._no_interface_constructor_types
+
+ map(constructor_function, interface.all(IDLExtAttrFunctionValue))
+
+ self._mark_usage(interface, check_dictionaries=check_dictionaries)
+
+ # Scan an attribute or operation for a dictionary or interface with NoInterfaceObject
+ # reference.
+ def _attribute_operation(self, interface, operation_attribute, check_dictionaries=True):
+ if check_dictionaries:
+ self._dictionaries_used_types = []
+ used = self._dictionary_used
+ else:
+ self._no_interfaces_used_types = [];
+ used = self._no_interface_used
+
+ map(used, operation_attribute.all(IDLType))
+
+ self._remember_usage(operation_attribute, check_dictionaries=check_dictionaries)
+ self._mark_usage(interface, operation_attribute, check_dictionaries=check_dictionaries)
+
+ # Iterator function for map to iterate over all constructor types
+ # (IDLExtAttrFunctionValue) that have a dictionary reference.
+ def _dictionary_constructor_types(self, node):
+ self._dictionaries_used_types = []
+ map(self._dictionary_used, node.all(IDLType))
+ self._remember_usage(node)
+
+ # Iterator function for map to iterate over all constructor types
+ # (IDLExtAttrFunctionValue) that reference an interface with NoInterfaceObject.
+ def _no_interface_constructor_types(self, node):
+ self._no_interfaces_used_types = [];
+ map(self._no_interface_used, node.all(IDLType))
+ self._remember_usage(node, check_dictionaries=False)
+
+ # Maximum width of each column.
+ def _TABULATE_WIDTH(self):
+ return 45
+
+ def _tabulate_title(self, row_title):
+ title_separator = "=" * self._TABULATE_WIDTH()
+ self._tabluate([title_separator, title_separator, title_separator])
+ self._tabluate(row_title)
+ self._tabluate([title_separator, title_separator, title_separator])
+
+ def _tabulate_break(self):
+ break_separator = "-" * self._TABULATE_WIDTH()
+ self._tabluate([break_separator, break_separator, break_separator])
+
+ def _tabluate(self, columns):
+ """Tabulate a list of columns for a row. Each item in columns is a column
+ value each column will be padded up to _TABULATE_WIDTH. Each
+ column starts/ends with a vertical bar '|' the format a row:
+
+ | columns[0] | columns[1] | columns[2] | ... |
+ """
+ if len(columns) > 0:
+ for column in columns:
+ value = '' if not column else column
+ sys.stdout.write('|{0:^{1}}'.format(value, self._TABULATE_WIDTH()))
+ else:
+ sys.stdout.write('|{0:^{1}}'.format('', self._TABULATE_WIDTH()))
+
+ sys.stdout.write('|\n')
« 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