# HG changeset patch # User Paul Boddie # Date 1477781466 -7200 # Node ID ba2614628b3f95212fc2fe06db9c5c8983b26a3c # Parent 8c1bebfcd574c0c092d5f09c16dbb3cd8ce19157 Fixed class namespace lookups that produced deferred references and thus inappropriate tracking names for globals during inspection. Fixed name reference code generation for parent-relative accesses. Changed name reference creation during translation to always use local names and for tracking names to only be computed when retrieving attribute access details. diff -r 8c1bebfcd574 -r ba2614628b3f common.py --- a/common.py Sat Oct 29 22:56:23 2016 +0200 +++ b/common.py Sun Oct 30 00:51:06 2016 +0200 @@ -643,7 +643,7 @@ elif path: return path - # Otherwise, establish a name in the current (module) namespace. + # Otherwise, establish a name in the current namespace. else: return self.get_object_path(name) diff -r 8c1bebfcd574 -r ba2614628b3f inspector.py --- a/inspector.py Sat Oct 29 22:56:23 2016 +0200 +++ b/inspector.py Sun Oct 30 00:51:06 2016 +0200 @@ -1264,7 +1264,7 @@ if not self.in_function and name not in predefined_constants: if self.in_class: - ref = self.get_object(self.get_object_path(name)) + ref = self.get_object(self.get_object_path(name), False) if not ref: ref = self.get_global_or_builtin(name) diff -r 8c1bebfcd574 -r ba2614628b3f modules.py --- a/modules.py Sat Oct 29 22:56:23 2016 +0200 +++ b/modules.py Sun Oct 30 00:51:06 2016 +0200 @@ -304,19 +304,22 @@ self.queue_module(module_name, True) return Reference("", "__builtins__.%s.%s" % (name, name)) - def get_object(self, path): + def get_object(self, path, defer=True): """ Get the details of an object with the given 'path'. Where the object - cannot be resolved, an unresolved reference is returned. + cannot be resolved, an unresolved reference is returned if 'defer' is + set to a true value (the default). Otherwise, None is returned. """ if self.objects.has_key(path): return self.objects[path] - else: + elif defer: ref = Reference("", path) self.deferred.append(ref) return ref + else: + return None def import_name_from_module(self, name, module_name): diff -r 8c1bebfcd574 -r ba2614628b3f translator.py --- a/translator.py Sat Oct 29 22:56:23 2016 +0200 +++ b/translator.py Sun Oct 30 00:51:06 2016 +0200 @@ -91,7 +91,7 @@ # Determine whether a qualified name is involved. - t = (self.expr and self.get_name() or self.name).rsplit(".", 1) + t = (self.get_name() or self.name).rsplit(".", 1) parent = len(t) > 1 and t[0] or None attrname = encode_path(t[-1]) @@ -122,6 +122,14 @@ context = ref.has_kind("") and encode_path(parent) or None return "((__attr) {%s, &%s})" % (context and "&%s" % context or "0", static_name) + # Qualified names must be converted into parent-relative accesses. + + elif parent: + return "__load_via_object(&%s, %s)" % ( + encode_path(parent), encode_symbol("pos", attrname)) + + # All other accesses involve the names as they were given. + else: return attrname @@ -603,7 +611,7 @@ # the complete access. name_ref = attr_expr and attr_expr.is_name() and attr_expr - name = name_ref and name_ref.name or None + name = name_ref and self.get_name_for_tracking(name_ref.name, name_ref and name_ref.final()) or None location = self.get_access_location(name) refs = self.get_referenced_attributes(location) @@ -1028,12 +1036,12 @@ # as in the inspector. path = self.get_object_path(n.name) - ref = self.importer.get_object(path) - name = self.get_name_for_tracking(n.name, ref and ref.final()) # Get the static identity of the name. ref = self.importer.identify(path) + if ref and not ref.get_name(): + ref = ref.alias(path) # Obtain any resolved names for non-assignment names. @@ -1045,7 +1053,7 @@ # static namespace members. The reference should be configured to return # such names. - return TrResolvedNameRef(name, ref, expr=expr) + return TrResolvedNameRef(n.name, ref, expr=expr) def process_not_node(self, n):