# HG changeset patch # User Paul Boddie # Date 1476996228 -7200 # Node ID 83d261448283a15686e6fc2500d1d08f73b22539 # Parent 0fcb1351544ee1912f0db6ce5adcf57cf86a817f Support invocation recording in attribute access modifiers. diff -r 0fcb1351544e -r 83d261448283 deducer.py --- a/deducer.py Thu Oct 20 15:00:27 2016 +0200 +++ b/deducer.py Thu Oct 20 22:43:48 2016 +0200 @@ -83,9 +83,10 @@ self.modified_attributes = {} - # Accesses that are assignments. + # Accesses that are assignments or invocations. self.reference_assignments = set() + self.reference_invocations = set() # Map locations to types, constrained indicators and attributes. @@ -796,8 +797,8 @@ # For each access, determine the name versions affected by # assignments. - for access_number, assignment in enumerate(modifiers): - if not assignment: + for access_number, (assignment, invocation) in enumerate(modifiers): + if not assignment and not invocation: continue if name: @@ -805,6 +806,10 @@ else: access_location = (path, None, attrname_str, 0) + if invocation: + self.reference_invocations.add(access_location) + continue + self.reference_assignments.add(access_location) # Associate assignments with usage. @@ -1955,6 +1960,7 @@ # Determine the method of access. is_assignment = location in self.reference_assignments + is_invocation = location in self.reference_invocations # Identified attribute that must be accessed via its parent. @@ -1964,7 +1970,9 @@ # Static, identified attribute. elif attr and attr.static(): - final_method = is_assignment and "static-assign" or "static" + final_method = is_assignment and "static-assign" or \ + is_invocation and "static-invoke" or \ + "static" origin = attr.final() # All other methods of access involve traversal. diff -r 0fcb1351544e -r 83d261448283 encoders.py --- a/encoders.py Thu Oct 20 15:00:27 2016 +0200 +++ b/encoders.py Thu Oct 20 22:43:48 2016 +0200 @@ -89,14 +89,14 @@ "Encode modifier 't' representing assignment status." - assignment = t - return assignment and "A" or "_" + assignment, invocation = t + return assignment and "=" or invocation and "!" or "_" def decode_modifier_term(s): "Decode modifier term 's' representing assignment status." - return s == "A" + return (s == "=", s == "!") @@ -181,6 +181,10 @@ "__test_common_instance", ) +encoding_ops = ( + "__encode_callable", + ) + def encode_access_instruction(instruction, subs): """ @@ -227,6 +231,14 @@ a[1] = encode_symbol("pos", arg) a.insert(2, encode_symbol("code", arg)) + # Replace encoded operations. + + elif op in encoding_ops: + origin = a[0] + kind = a[1] + op = "__load_function" + a = [kind == "" and encode_instantiator_pointer(origin) or encode_function_pointer(origin)] + argstr = "(%s)" % ", ".join(a) # Substitute the first element of the instruction, which may not be an diff -r 0fcb1351544e -r 83d261448283 inspector.py --- a/inspector.py Thu Oct 20 15:00:27 2016 +0200 +++ b/inspector.py Thu Oct 20 22:43:48 2016 +0200 @@ -401,12 +401,11 @@ if not isinstance(name_ref, NameRef): # includes ResolvedNameRef - assignment = isinstance(n, compiler.ast.AssAttr) - init_item(self.attr_accesses, path, set) self.attr_accesses[path].add(attrnames) - self.record_access_details(None, attrnames, assignment) + self.record_access_details(None, attrnames, self.in_assignment, + self.in_invocation) del self.attrs[0] return @@ -460,7 +459,8 @@ name, attrname), path, n) self.record_branches_for_access(branches, name, attrnames) - access_number = self.record_access_details(name, attrnames, self.in_assignment) + access_number = self.record_access_details(name, attrnames, + self.in_assignment, self.in_invocation) del self.attrs[0] return AccessRef(name, attrnames, access_number) @@ -844,7 +844,7 @@ if branches: self.record_branches_for_access(branches, n.name, None) - access_number = self.record_access_details(n.name, None, False) + access_number = self.record_access_details(n.name, None, False, False) return LocalNameRef(n.name, access_number) # Possible global or built-in name. @@ -1118,7 +1118,7 @@ init_item(attr_accessor_branches, access, list) attr_accessor_branches[access].append(branches) - def record_access_details(self, name, attrnames, assignment): + def record_access_details(self, name, attrnames, assignment, invocation): """ For the given 'name' and 'attrnames', record an access indicating @@ -1135,7 +1135,7 @@ init_item(self.attr_access_modifiers[path], access, list) access_number = len(self.attr_access_modifiers[path][access]) - self.attr_access_modifiers[path][access].append(assignment) + self.attr_access_modifiers[path][access].append((assignment, invocation)) return access_number def record_global_access_details(self, name, attrnames):