# HG changeset patch # User Paul Boddie # Date 1309125277 -7200 # Node ID c57594e433383bddc6b284d9b1d1c2a0337d2d0f # Parent 26002b8d2dce8b9b3db10879a1c9c5f82289151f Moved the definition of accessor types into the function finalisation code, moving finalisation itself to after the object table has been redefined, resulting in substantially fewer accessor types being generated for any given set of attribute names (usage) where coverage analysis has eliminated many objects from a program. Fixed the presentation of various things in reports, adding support for some missing AST nodes. diff -r 26002b8d2dce -r c57594e43338 micropython/__init__.py --- a/micropython/__init__.py Sun Jun 26 17:01:29 2011 +0200 +++ b/micropython/__init__.py Sun Jun 26 23:54:37 2011 +0200 @@ -37,8 +37,7 @@ which the functionality of the micropython package may be accessed. """ -from micropython.common import ObjectSet, ProcessingError, TableError, \ - TableGenerationError +from micropython.common import * import micropython.ast import micropython.data import micropython.opt @@ -95,13 +94,14 @@ self.get_parameter_table() self.importer.vacuum(objtable) - self.importer.finalise() # Now remove unneeded things from the tables. - self.get_object_table(reset=1) + objtable = self.get_object_table(reset=1) self.get_parameter_table(reset=1) + self.importer.finalise(objtable) + def get_image(self, with_builtins=0): """ @@ -432,7 +432,7 @@ self.vacuumed = 1 - def finalise(self): + def finalise(self, objtable): "Finalise the program (which should have been vacuumed first)." @@ -447,7 +447,7 @@ # Prepare module information again. for module in self.get_modules(): - module.finalise() + module.finalise(objtable) self.finalised = 1 @@ -612,25 +612,9 @@ # Using all attribute names for a particular name, attempt to get # specific object types. - all_objtypes = set() - - for attrnames in usage: - objtypes = objtable.all_possible_objects_plus_status(attrnames) - if not objtypes: - print "Warning: usage in %r for %r finds no object supporting all attributes %r" % (from_name, name, attrnames) - objtypes = objtable.any_possible_objects_plus_status(attrnames) - if not objtypes: - print "Warning: usage in %r for %r finds no object supporting any attributes %r" % (from_name, name, attrnames) + all_objtypes = get_object_types_for_usage(usage, objtable, name, from_name) - all_objtypes.update(objtypes) - - # Record the object types for generating guards. - - if user is not None: - if not hasattr(user, "_attrtypes"): - user._attrtypes = {} - - user._attrtypes[name] = all_objtypes + # Investigate the object types. self._collect_attributes_for_types(from_name, objtable, all_objtypes, usage) diff -r 26002b8d2dce -r c57594e43338 micropython/common.py --- a/micropython/common.py Sun Jun 26 17:01:29 2011 +0200 +++ b/micropython/common.py Sun Jun 26 23:54:37 2011 +0200 @@ -260,6 +260,30 @@ return hasattr(node, "unit") and node.unit.parent.has_key(node.unit.name) +def get_object_types_for_usage(usage, objtable, name, unit_name): + + """ + Return for the given attribute 'usage', using the 'objtable', the object + types which satisfy such usage, reporting any problems for the given 'name' + and 'unit_name'. + """ + + all_objtypes = set() + + for attrnames in usage: + objtypes = objtable.all_possible_objects_plus_status(attrnames) + if not objtypes: + print "Warning: usage in %r for %r finds no object supporting all attributes %r" % ( + unit_name, name, attrnames) + objtypes = objtable.any_possible_objects_plus_status(attrnames) + if not objtypes: + print "Warning: usage in %r for %r finds no object supporting any attributes %r" % ( + unit_name, name, attrnames) + + all_objtypes.update(objtypes) + + return all_objtypes + # Errors. class ProcessingError(Exception): diff -r 26002b8d2dce -r c57594e43338 micropython/data.py --- a/micropython/data.py Sun Jun 26 17:01:29 2011 +0200 +++ b/micropython/data.py Sun Jun 26 23:54:37 2011 +0200 @@ -143,6 +143,9 @@ # Administrative methods. + def finalise(self, objtable): + self.finalise_attributes() + def items_for_vacuum(self): return self.items() + self.lambdas.items() @@ -1777,6 +1780,10 @@ # Administrative methods. + def finalise(self, objtable): + self.finalise_attributes() + self.finalise_users(objtable) + def items_for_vacuum(self): return self.lambdas.items() @@ -1833,6 +1840,17 @@ return i + def finalise_users(self, objtable): + + "Record the object types for generating guards." + + # Visit each user and examine the attribute usage for each name. + + for user in self.all_attribute_users: + user._attrtypes = {} + for name, usage in user._attrcombined.items(): + user._attrtypes[name] = get_object_types_for_usage(usage, objtable, name, self.full_name()) + def as_instantiator(self): "Make an instantiator function from a method, keeping all arguments." diff -r 26002b8d2dce -r c57594e43338 micropython/inspect.py --- a/micropython/inspect.py Sun Jun 26 17:01:29 2011 +0200 +++ b/micropython/inspect.py Sun Jun 26 23:54:37 2011 +0200 @@ -229,12 +229,12 @@ for obj in self.all_objects: obj.unfinalise_attributes() - def finalise(self): + def finalise(self, objtable): "Finalise the module." for obj in self.all_objects: - obj.finalise_attributes() + obj.finalise(objtable) def add_object(self, obj, any_scope=0): diff -r 26002b8d2dce -r c57594e43338 micropython/report.py --- a/micropython/report.py Sun Jun 26 17:01:29 2011 +0200 +++ b/micropython/report.py Sun Jun 26 23:54:37 2011 +0200 @@ -236,7 +236,10 @@ can be used to customise the CSS classes employed. """ - self._summary_link(module.full_name(), obj.full_name(), obj.name, classes) + if isinstance(obj, Class) or (isinstance(obj, Function) and obj.is_method()): + self._summary_link(module.full_name(), obj.full_name(), obj.name, classes) + else: + self._span(obj.name, classes) def _object_name_ref(self, module, obj, name=None, classes=None): @@ -268,7 +271,7 @@ def _op(self, symbol, name=None, leading=0, trailing=1): if leading: self.stream.write(" ") - self._span_start("operation") + self._span_start(name and "operation" or None) self._span(symbol, "operator") if name is not None: self._popup_start() @@ -834,7 +837,7 @@ self._accessor_end(target_names) self._span_start("attr") self.stream.write(".") - self._name(node.attrname) + self._span(node.attrname, "attrname") self._span_end() self._span_end() @@ -858,6 +861,12 @@ def visitBitand(self, node): self._visitBitBinary(node, "bitand", "&") + def visitBitor(self, node): + self._visitBitBinary(node, "bitor", "|") + + def visitBitxor(self, node): + self._visitBitBinary(node, "bitxor", "^") + def visitCallFunc(self, node): self._span_start("callfunc") self.dispatch(node.node)