# HG changeset patch # User Paul Boddie # Date 1479164421 -3600 # Node ID c4236e61a4f682f423e480e860768e72faf83eca # Parent b7860ad65334408782d9e9023227095fd0073ecc Attempt to provide usable references for inter-module dependencies, identifying them completely when object identity information is needed, exposing module provider information otherwise. Removed tests for "" references in cached output since inter-module dependencies will appear as such in the name references section of each file. diff -r b7860ad65334 -r c4236e61a4f6 importer.py --- a/importer.py Sun Nov 13 22:18:29 2016 +0100 +++ b/importer.py Tue Nov 15 00:00:21 2016 +0100 @@ -187,6 +187,15 @@ "Identify 'name' using stored object and external name records." + ref = self.follow(name) + if ref and ref.has_kind(""): + ref = self.follow(ref.get_origin()) + return ref + + def follow(self, name): + + "Identify 'name' using stored object and external name records." + ref = self.objects.get(name) if not ref or ref.has_kind(""): ref = self.all_name_references.get(name) or ref @@ -248,10 +257,7 @@ "Return from 'object_type' the details of module attribute 'attrname'." - if attrname in self.all_module_attrs[object_type]: - return self.get_object("%s.%s" % (object_type, attrname)) - else: - return None + return self.identify("%s.%s" % (object_type, attrname)) # Convenience methods for deducing which kind of object provided an # attribute. @@ -406,8 +412,8 @@ # Resolve all deferred references in each module. for ref in module.deferred: - found = self.find_dependency(ref) - if not found: + dependency = self.find_dependency(ref) + if not dependency: self.missing.add((module.name, ref.get_origin())) # Record the resolved names and identify required modules. @@ -416,9 +422,17 @@ # Find the providing module of this reference. # Where definitive details of the origin cannot be found, # identify the provider using the deferred reference. - # NOTE: This may need to test for static origins. + + provider = self.get_module_provider(dependency.unresolved() and ref or dependency) + + # Only mutate references to the eventual object if it is + # static. Otherwise, maintain the closest referrer. - provider = self.get_module_provider(found.unresolved() and ref or found) + if dependency.static(): + found = dependency + else: + found = self.find_reference(ref) + ref.mutate(found) if provider: @@ -468,7 +482,22 @@ found = set() while ref and ref.has_kind("") and not ref in found: found.add(ref) - ref = self.identify(ref.get_origin()) + ref = self.follow(ref.get_origin()) + return ref + + def find_reference(self, ref): + + "Find the ultimate usable reference for 'ref'." + + found = set() + while ref: + found.add(ref) + next_ref = self.follow(ref.get_origin()) + if not next_ref or next_ref in found: + return ref + if not next_ref.has_kind("") and not next_ref.static(): + return ref + ref = next_ref return ref def get_module_provider(self, ref): diff -r b7860ad65334 -r c4236e61a4f6 test_all.sh --- a/test_all.sh Sun Nov 13 22:18:29 2016 +0100 +++ b/test_all.sh Tue Nov 15 00:00:21 2016 +0100 @@ -41,16 +41,6 @@ echo "$FILENAME..." 1>&2 if ! ./lplc "$FILENAME" -r ; then exit 1 ; fi - # Check for unresolved names in the cache. - - echo " (depends)..." 1>&2 - if grep '' -r "_cache" && \ - ! expect_failure ; then - - echo "Unresolved names in the cache." 1>&2 - exit 1 - fi - # Check for type warnings in deduction output. echo " (warnings)..." 1>&2