1.1 --- a/inspector.py Wed Oct 19 16:37:01 2016 +0200
1.2 +++ b/inspector.py Wed Oct 19 21:05:24 2016 +0200
1.3 @@ -21,7 +21,7 @@
1.4 """
1.5
1.6 from branching import BranchTracker
1.7 -from common import get_argnames, init_item, predefined_constants
1.8 +from common import CommonModule, get_argnames, init_item, predefined_constants
1.9 from modules import BasicModule, CacheWritingModule, InspectionNaming
1.10 from errors import InspectError
1.11 from referencing import Reference
1.12 @@ -45,6 +45,14 @@
1.13 self.in_class = False
1.14 self.in_conditional = False
1.15 self.in_invocation = False
1.16 +
1.17 + # Attribute chain state management.
1.18 +
1.19 + self.chain_assignment = []
1.20 + self.chain_invocation = []
1.21 +
1.22 + # Accesses to global attributes.
1.23 +
1.24 self.global_attr_accesses = {}
1.25
1.26 # Usage tracking.
1.27 @@ -367,20 +375,10 @@
1.28
1.29 "Process the given attribute access node 'n'."
1.30
1.31 - # Parts of the attribute chain are neither invoked nor assigned.
1.32 -
1.33 - in_invocation = self.in_invocation
1.34 - self.in_invocation = False
1.35 - in_assignment = self.in_assignment
1.36 - self.in_assignment = False
1.37 -
1.38 # Obtain any completed chain and return the reference to it.
1.39
1.40 name_ref = self.process_attribute_chain(n)
1.41
1.42 - self.in_invocation = in_invocation
1.43 - self.in_assignment = in_assignment
1.44 -
1.45 if self.have_access_expression(n):
1.46 return name_ref
1.47
1.48 @@ -455,15 +453,14 @@
1.49 # Record attribute usage in the tracker, and record the branch
1.50 # information for the access.
1.51
1.52 - branches = tracker.use_attribute(name, attrname, self.in_invocation,
1.53 - self.in_assignment and immediate_access)
1.54 + branches = tracker.use_attribute(name, attrname, self.in_invocation, assignment)
1.55
1.56 if not branches:
1.57 raise InspectError("Name %s is accessed using %s before an assignment." % (
1.58 name, attrname), path, n)
1.59
1.60 self.record_branches_for_access(branches, name, attrnames)
1.61 - access_number = self.record_access_details(name, attrnames, assignment)
1.62 + access_number = self.record_access_details(name, attrnames, self.in_assignment)
1.63
1.64 del self.attrs[0]
1.65 return AccessRef(name, attrnames, access_number)
1.66 @@ -992,6 +989,26 @@
1.67
1.68 tracker.resume_broken_branches()
1.69
1.70 + # Attribute chain handling.
1.71 +
1.72 + def reset_attribute_chain(self):
1.73 +
1.74 + "Reset the attribute chain for a subexpression of an attribute access."
1.75 +
1.76 + CommonModule.reset_attribute_chain(self)
1.77 + self.chain_assignment.append(self.in_assignment)
1.78 + self.chain_invocation.append(self.in_invocation)
1.79 + self.in_assignment = False
1.80 + self.in_invocation = False
1.81 +
1.82 + def restore_attribute_chain(self, attrs):
1.83 +
1.84 + "Restore the attribute chain for an attribute access."
1.85 +
1.86 + CommonModule.restore_attribute_chain(self, attrs)
1.87 + self.in_assignment = self.chain_assignment.pop()
1.88 + self.in_invocation = self.chain_invocation.pop()
1.89 +
1.90 # Branch tracking methods.
1.91
1.92 def start_tracking(self, names):