1.1 --- a/importer.py Sun Nov 13 22:18:29 2016 +0100
1.2 +++ b/importer.py Tue Nov 15 00:00:21 2016 +0100
1.3 @@ -187,6 +187,15 @@
1.4
1.5 "Identify 'name' using stored object and external name records."
1.6
1.7 + ref = self.follow(name)
1.8 + if ref and ref.has_kind("<depends>"):
1.9 + ref = self.follow(ref.get_origin())
1.10 + return ref
1.11 +
1.12 + def follow(self, name):
1.13 +
1.14 + "Identify 'name' using stored object and external name records."
1.15 +
1.16 ref = self.objects.get(name)
1.17 if not ref or ref.has_kind("<module>"):
1.18 ref = self.all_name_references.get(name) or ref
1.19 @@ -248,10 +257,7 @@
1.20
1.21 "Return from 'object_type' the details of module attribute 'attrname'."
1.22
1.23 - if attrname in self.all_module_attrs[object_type]:
1.24 - return self.get_object("%s.%s" % (object_type, attrname))
1.25 - else:
1.26 - return None
1.27 + return self.identify("%s.%s" % (object_type, attrname))
1.28
1.29 # Convenience methods for deducing which kind of object provided an
1.30 # attribute.
1.31 @@ -406,8 +412,8 @@
1.32 # Resolve all deferred references in each module.
1.33
1.34 for ref in module.deferred:
1.35 - found = self.find_dependency(ref)
1.36 - if not found:
1.37 + dependency = self.find_dependency(ref)
1.38 + if not dependency:
1.39 self.missing.add((module.name, ref.get_origin()))
1.40
1.41 # Record the resolved names and identify required modules.
1.42 @@ -416,9 +422,17 @@
1.43 # Find the providing module of this reference.
1.44 # Where definitive details of the origin cannot be found,
1.45 # identify the provider using the deferred reference.
1.46 - # NOTE: This may need to test for static origins.
1.47 +
1.48 + provider = self.get_module_provider(dependency.unresolved() and ref or dependency)
1.49 +
1.50 + # Only mutate references to the eventual object if it is
1.51 + # static. Otherwise, maintain the closest referrer.
1.52
1.53 - provider = self.get_module_provider(found.unresolved() and ref or found)
1.54 + if dependency.static():
1.55 + found = dependency
1.56 + else:
1.57 + found = self.find_reference(ref)
1.58 +
1.59 ref.mutate(found)
1.60
1.61 if provider:
1.62 @@ -468,7 +482,22 @@
1.63 found = set()
1.64 while ref and ref.has_kind("<depends>") and not ref in found:
1.65 found.add(ref)
1.66 - ref = self.identify(ref.get_origin())
1.67 + ref = self.follow(ref.get_origin())
1.68 + return ref
1.69 +
1.70 + def find_reference(self, ref):
1.71 +
1.72 + "Find the ultimate usable reference for 'ref'."
1.73 +
1.74 + found = set()
1.75 + while ref:
1.76 + found.add(ref)
1.77 + next_ref = self.follow(ref.get_origin())
1.78 + if not next_ref or next_ref in found:
1.79 + return ref
1.80 + if not next_ref.has_kind("<depends>") and not next_ref.static():
1.81 + return ref
1.82 + ref = next_ref
1.83 return ref
1.84
1.85 def get_module_provider(self, ref):
2.1 --- a/test_all.sh Sun Nov 13 22:18:29 2016 +0100
2.2 +++ b/test_all.sh Tue Nov 15 00:00:21 2016 +0100
2.3 @@ -41,16 +41,6 @@
2.4 echo "$FILENAME..." 1>&2
2.5 if ! ./lplc "$FILENAME" -r ; then exit 1 ; fi
2.6
2.7 - # Check for unresolved names in the cache.
2.8 -
2.9 - echo " (depends)..." 1>&2
2.10 - if grep '<depends>' -r "_cache" && \
2.11 - ! expect_failure ; then
2.12 -
2.13 - echo "Unresolved names in the cache." 1>&2
2.14 - exit 1
2.15 - fi
2.16 -
2.17 # Check for type warnings in deduction output.
2.18
2.19 echo " (warnings)..." 1>&2