# HG changeset patch # User Paul Boddie # Date 1381682430 -7200 # Node ID 19cd0e03f46dffe4acecf018be01a1554ccffb66 # Parent d9346e98f2bdd4c60fdc0a6b78ef8b1184ac0c8e Added a static definition counter for numbering class and function definitions. Made the report generation use the original name for class and function labels. diff -r d9346e98f2bd -r 19cd0e03f46d TO_DO.txt --- a/TO_DO.txt Sun Oct 13 15:45:26 2013 +0200 +++ b/TO_DO.txt Sun Oct 13 18:40:30 2013 +0200 @@ -1,6 +1,3 @@ -Add a namespace attribute counter for specific definitions/declarations of things like -classes and functions, used to number multiple definitions in a given module. - Name usage types: as parameters, as base classes, as callables. This potentially restricts attribute usage effects because names mentioned as base classes are not propagated and made freely available for use in attribute accesses. diff -r d9346e98f2bd -r 19cd0e03f46d micropython/data.py --- a/micropython/data.py Sun Oct 13 15:45:26 2013 +0200 +++ b/micropython/data.py Sun Oct 13 18:40:30 2013 +0200 @@ -365,6 +365,10 @@ self.assignments = None + # Number of static "class" or "def" assignments per name. + + self.static_assignments = 0 + # Value-related methods. def get_contexts(self): @@ -1474,7 +1478,9 @@ original_name = name if parent.has_key(name): - name = "%s#%d" % (name, parent[name].assignments + 1) + assignments = parent[name].static_assignments + if assignments > 1: + name = "%s#%d" % (name, assignments + 1) cls = Class(name, parent, module, node, original_name) @@ -1497,15 +1503,9 @@ original_name = name if parent.has_key(name): - # NOTE: Handle AtLeast(n) situations, such as in cases where modules - # NOTE: may mutate others (doctest "monkeypatching" linecache, for - # NOTE: example). - # NOTE: Should probably have a separate attribute tracking actual - # NOTE: declarations rather than use the assignments attribute. - assignments = parent[name].assignments - if isinstance(assignments, AtLeast): - assignments = assignments.count - name = "%s#%d" % (name, assignments + 1) + assignments = parent[name].static_assignments + if assignments > 1: + name = "%s#%d" % (name, assignments + 1) fn = Function(name, parent, argnames, defaults, has_star, has_dstar, dynamic_def, module, node, original_name) diff -r d9346e98f2bd -r 19cd0e03f46d micropython/inspect.py --- a/micropython/inspect.py Sun Oct 13 15:45:26 2013 +0200 +++ b/micropython/inspect.py Sun Oct 13 18:40:30 2013 +0200 @@ -415,9 +415,13 @@ namespaces = namespaces or self.namespaces return len(namespaces) > 1 and isinstance(namespaces[-2], Class) - def store(self, name, obj): + def store(self, name, obj, static_def=False): - "Record attribute or local 'name', storing 'obj'." + """ + Record attribute or local 'name', storing 'obj'. Where 'static_def' is + specified and set to a true value, the namespace will record a static + definition for the given name. + """ # Store in the module. @@ -425,7 +429,7 @@ if self.in_loop and self.used_in_scope(name, "builtins"): raise InspectError("Name %r already used as a built-in." % name) else: - self.set(name, obj, not self.in_loop) + ns = self # Or store locally. @@ -437,7 +441,11 @@ elif self.in_loop and locals.used_in_scope(name, "builtins"): raise InspectError("Name %r already used as a built-in." % name) else: - locals.set(name, obj, not self.in_loop) + ns = locals + + ns.set(name, obj, not self.in_loop) + if static_def: + ns.get(name).static_assignments += 1 def store_lambda(self, obj): @@ -800,7 +808,7 @@ # Store the function. if name is not None: - self.store(name, function) + self.store(name, function, static_def=True) else: self.store_lambda(function) @@ -1019,7 +1027,7 @@ # Make an entry for the class in the parent namespace. self.namespaces.pop() - self.store(node.name, cls) + self.store(node.name, cls, static_def=True) self.define_attribute_user(node) self.add_object(cls) diff -r d9346e98f2bd -r 19cd0e03f46d micropython/report.py --- a/micropython/report.py Sun Oct 13 15:45:26 2013 +0200 +++ b/micropython/report.py Sun Oct 13 18:40:30 2013 +0200 @@ -271,10 +271,15 @@ can be used to customise the CSS classes employed. """ + if isinstance(obj, (Class, Function)): + name = obj.original_name + else: + name = obj.name + if isinstance(obj, Class) or (isinstance(obj, Function) and obj.is_method()): - self._summary_link(module.full_name(), obj.full_name(), obj.name, classes) + self._summary_link(module.full_name(), obj.full_name(), name, classes) else: - self._span(obj.name, classes) + self._span(name, classes) def _object_name_ref(self, module, obj, name=None, classes=None):