# HG changeset patch # User Paul Boddie # Date 1487521891 -3600 # Node ID b6cda55e96b9a49f0738dc4d08d2c3efd0d2c62f # Parent 7185fb95c3bc88f0eec78b978311eecf3fc26cbe Introduced the name tracking namespace path to alias details so that the correct access locations can be associated with aliases referencing globals. diff -r 7185fb95c3bc -r b6cda55e96b9 common.py --- a/common.py Sun Feb 12 23:23:28 2017 +0100 +++ b/common.py Sun Feb 19 17:31:31 2017 +0100 @@ -741,14 +741,14 @@ return isinstance(node.expr, compiler.ast.Getattr) - def get_name_for_tracking(self, name, path=None): + def get_name_for_tracking(self, name, ref=None): """ Return the name to be used for attribute usage observations involving - the given 'name' in the current namespace. If 'path' is indicated and - the name is being used outside a function, return the path value; - otherwise, return a path computed using the current namespace and the - given name. + the given 'name' in the current namespace. If 'ref' is indicated and + the name is being used outside a function, return the origin information + from 'ref'; otherwise, return a path computed using the current + namespace and the given name. The intention of this method is to provide a suitably-qualified name that can be tracked across namespaces. Where globals are being @@ -768,8 +768,13 @@ # For static namespaces, use the given qualified name. - elif path: - return path + elif ref and ref.static(): + return ref.get_origin() + + # For non-static objects in static namespaces, use any alias. + + elif ref and ref.get_name(): + return ref.get_name() # Otherwise, establish a name in the current namespace. diff -r 7185fb95c3bc -r b6cda55e96b9 deducer.py --- a/deducer.py Sun Feb 12 23:23:28 2017 +0100 +++ b/deducer.py Sun Feb 19 17:31:31 2017 +0100 @@ -917,9 +917,9 @@ # For each version of the name, obtain the access location. - for version, (original_name, attrnames, access_number) in all_aliases.items(): + for version, (original_path, original_name, attrnames, access_number) in all_aliases.items(): accessor_location = (path, name, None, version) - access_location = (path, original_name, attrnames, access_number) + access_location = (original_path, original_name, attrnames, access_number) init_item(self.alias_index, accessor_location, list) self.alias_index[accessor_location].append(access_location) diff -r 7185fb95c3bc -r b6cda55e96b9 inspector.py --- a/inspector.py Sun Feb 12 23:23:28 2017 +0100 +++ b/inspector.py Sun Feb 19 17:31:31 2017 +0100 @@ -412,7 +412,7 @@ # if assigned in the namespace, or using an external name # (presently just globals within classes). - name = self.get_name_for_tracking(name_ref.name, name_ref.final()) + name = self.get_name_for_tracking(name_ref.name, name_ref.reference()) tracker = self.trackers[-1] immediate_access = len(self.attrs) == 1 diff -r 7185fb95c3bc -r b6cda55e96b9 modules.py --- a/modules.py Sun Feb 12 23:23:28 2017 +0100 +++ b/modules.py Sun Feb 19 17:31:31 2017 +0100 @@ -495,11 +495,11 @@ f.readline() # "aliased names:" line = f.readline().rstrip() while line: - name, version, original_name, attrnames, number = self._get_fields(line, 5) + name, version, path, original_name, attrnames, number = self._get_fields(line, 5) init_item(self.aliased_names, name, dict) if number == "{}": number = None else: number = int(number) - self.aliased_names[name][int(version)] = (original_name, attrnames != "{}" and attrnames or None, number) + self.aliased_names[name][int(version)] = (path, original_name, attrnames != "{}" and attrnames or None, number) line = f.readline().rstrip() def _get_function_parameters(self, f): @@ -785,8 +785,8 @@ versions = aliases.items() versions.sort() for version, alias in versions: - original_name, attrnames, number = alias - print >>f, name, version, original_name, attrnames or "{}", number is None and "{}" or number + path, original_name, attrnames, number = alias + print >>f, name, version, path, original_name, attrnames or "{}", number is None and "{}" or number print >>f print >>f, "function parameters:" diff -r 7185fb95c3bc -r b6cda55e96b9 resolving.py --- a/resolving.py Sun Feb 12 23:23:28 2017 +0100 +++ b/resolving.py Sun Feb 19 17:31:31 2017 +0100 @@ -3,7 +3,7 @@ """ Name resolution. -Copyright (C) 2016 Paul Boddie +Copyright (C) 2016, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -289,7 +289,13 @@ if not ref: if not invocation: - aliased_names[i] = name_ref.original_name, name_ref.attrnames, name_ref.number + + # Record the path used for tracking purposes + # alongside original name, attribute and access + # number details. + + aliased_names[i] = path, name_ref.original_name, name_ref.attrnames, name_ref.number + continue # Attempt to resolve a plain name reference. @@ -303,7 +309,13 @@ if not origin: if not invocation: - aliased_names[i] = name_ref.name, None, name_ref.number + + # Record the path used for tracking purposes + # alongside original name, attribute and access + # number details. + + aliased_names[i] = path, name_ref.name, None, name_ref.number + continue ref = self.get_resolved_object(origin) diff -r 7185fb95c3bc -r b6cda55e96b9 translator.py --- a/translator.py Sun Feb 12 23:23:28 2017 +0100 +++ b/translator.py Sun Feb 19 17:31:31 2017 +0100 @@ -726,7 +726,7 @@ # the complete access. name_ref = attr_expr and attr_expr.is_name() and attr_expr - name = name_ref and self.get_name_for_tracking(name_ref.name, name_ref and name_ref.final()) or None + name = name_ref and self.get_name_for_tracking(name_ref.name, name_ref and name_ref.reference()) or None location = self.get_access_location(name, self.attrs) refs = self.get_referenced_attributes(location)