1.1 --- a/TO_DO.txt Tue Jun 05 01:54:54 2012 +0200
1.2 +++ b/TO_DO.txt Sat Jun 09 02:01:56 2012 +0200
1.3 @@ -94,8 +94,6 @@
1.4 Self-related Usage
1.5 ------------------
1.6
1.7 -Usage of self to restrict attribute usage observations and coverage.
1.8 -
1.9 Perform attribute usage on attributes of self as names, potentially combining observations
1.10 across methods.
1.11
2.1 --- a/micropython/data.py Tue Jun 05 01:54:54 2012 +0200
2.2 +++ b/micropython/data.py Sat Jun 09 02:01:56 2012 +0200
2.3 @@ -390,7 +390,6 @@
2.4 # usage with the usage recorded directly on the user.
2.5
2.6 self.get_usage_from_contributors(user)
2.7 - self.set_contributors(user)
2.8
2.9 # Record the defining user on each contributor.
2.10
2.11 @@ -485,21 +484,6 @@
2.12 attrtypes[name] = objtypes
2.13 return attrtypes
2.14
2.15 - def set_contributors(self, node):
2.16 - if not hasattr(node, "_attrcontributors"):
2.17 - node._attrcontributors = None
2.18 - all_contributors = set()
2.19 -
2.20 - for contributor in node._attrbranches:
2.21 - all_contributors.add(contributor)
2.22 - self.set_contributors(contributor)
2.23 -
2.24 - contributors = contributor._attrcontributors
2.25 - if contributors is not None:
2.26 - all_contributors.update(contributors)
2.27 -
2.28 - node._attrcontributors = all_contributors
2.29 -
2.30 def get_usage_from_contributors(self, node):
2.31
2.32 """
2.33 @@ -513,6 +497,7 @@
2.34
2.35 if not hasattr(node, "_attrcombined"):
2.36 node._attrcombined = None
2.37 + node._attrcontributors = None
2.38
2.39 for contributor in node._attrbranches:
2.40
2.41 @@ -522,23 +507,33 @@
2.42
2.43 # Collect unfinished contributors and affected nodes.
2.44
2.45 - if node._attrcombined is None:
2.46 + # Where the contributor is already set to None, a loop has
2.47 + # occurred and this node will need to have its usage
2.48 + # recalculated later for the unfinished contributor.
2.49 +
2.50 + if contributor._attrcombined is None:
2.51 if not unfinished.has_key(contributor):
2.52 unfinished[contributor] = []
2.53 unfinished[contributor].append(node)
2.54 continue
2.55
2.56 + # Where the contributor provides usage details, it may also
2.57 + # communicate unfinished contributor information. As a
2.58 + # consequence, this node is also affected.
2.59 +
2.60 for unfinished_contributor, nodes in unfinished_contributors.items():
2.61 if not unfinished.has_key(unfinished_contributor):
2.62 unfinished[unfinished_contributor] = nodes
2.63 else:
2.64 unfinished[unfinished_contributor] += nodes
2.65
2.66 - unfinished[contributor].append(node)
2.67 + if node not in unfinished[unfinished_contributor]:
2.68 + unfinished[unfinished_contributor].append(node)
2.69
2.70 # Set the current state of the usage on this node.
2.71
2.72 - node._attrcombined = self.get_usage_from_contributors_for_node(node)
2.73 + node._attrcombined, node._attrcontributors = \
2.74 + self.get_usage_from_contributors_for_node(node)
2.75
2.76 # Complete unfinished contributors relying on this node.
2.77
2.78 @@ -547,7 +542,10 @@
2.79 for contributor in unfinished[node]:
2.80 if not contributor in processed:
2.81 processed.add(contributor)
2.82 - contributor._attrcombined = self.get_usage_from_contributors_for_node(contributor)
2.83 +
2.84 + contributor._attrcombined, contributor._attrcontributors = \
2.85 + self.get_usage_from_contributors_for_node(contributor)
2.86 +
2.87 del unfinished[node]
2.88
2.89 return unfinished
2.90 @@ -558,12 +556,18 @@
2.91
2.92 contributor_usage = {}
2.93 all_contributions = []
2.94 + all_contributors = set()
2.95
2.96 for contributor in node._attrbranches:
2.97 usage = contributor._attrcombined
2.98 if usage is not None:
2.99 all_contributions.append(usage)
2.100
2.101 + all_contributors.add(contributor)
2.102 + contributors = contributor._attrcontributors
2.103 + if contributors is not None:
2.104 + all_contributors.update(contributors)
2.105 +
2.106 # Get contributed usage for each contributor.
2.107 # This gathers usage for each name such as {(a, b), (c, d)} and
2.108 # {(a, b), (e, f)} into a single set {(a, b), (c, d), (e, f)}.
2.109 @@ -578,7 +582,7 @@
2.110 # Thus, usage of {(f, g)} combined with {(a, b), (c, d)} would give
2.111 # {(f, g, a, b), (f, g, c, d)}.
2.112
2.113 - return combine_mapping_dicts(deepen_mapping_dict(node._attrnames), contributor_usage)
2.114 + return combine_mapping_dicts(deepen_mapping_dict(node._attrnames), contributor_usage), all_contributors
2.115
2.116 def use_attribute(self, name, attrname, value=None):
2.117
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/tests/attribute_access_type_restriction_conditional_nested.py Sat Jun 09 02:01:56 2012 +0200
3.3 @@ -0,0 +1,25 @@
3.4 +#!/usr/bin/env python
3.5 +
3.6 +class C:
3.7 + def f(self):
3.8 + return 1
3.9 + def g(self):
3.10 + return 2
3.11 +
3.12 +class D:
3.13 + def g(self):
3.14 + return 3
3.15 +
3.16 +def test_conditional(x, obj):
3.17 + obj.f()
3.18 + if x:
3.19 + if x:
3.20 + a = obj.g()
3.21 + return a
3.22 + return 1
3.23 +
3.24 +c = C()
3.25 +d = D()
3.26 +result1_2 = test_conditional(1, c)
3.27 +
3.28 +# vim: tabstop=4 expandtab shiftwidth=4