1.1 --- a/docs/annotations.txt Wed Feb 29 00:39:20 2012 +0100
1.2 +++ b/docs/annotations.txt Mon Mar 05 00:25:11 2012 +0100
1.3 @@ -12,8 +12,13 @@
1.4 _attrcombined defines a dictionary mapping local names to sets of
1.5 attribute names found to be used with those names for the
1.6 entire lifetime of a particular attribute user
1.7 -_attrtypes defines types deduced from the combined attribute usage
1.8 - details
1.9 +_attrmerged defines a dictionary mapping local names to sets of
1.10 + attribute names merging combined observations with locally
1.11 + applicable observations, indicating usage specific to a
1.12 + region of the code
1.13 +_attrtypes defines types deduced either from combined attribute usage
1.14 + details (for users) or from merged attribute usage details
1.15 + (for other nodes)
1.16 _attrdefs defines definition-related users which consume usage details
1.17 from the node
1.18
2.1 --- a/micropython/common.py Wed Feb 29 00:39:20 2012 +0100
2.2 +++ b/micropython/common.py Mon Mar 05 00:25:11 2012 +0100
2.3 @@ -155,7 +155,17 @@
2.4
2.5 def update_mapping_dict(new_dict, dicts):
2.6
2.7 - "Update 'new_dict' with the contents of the set dictionary 'dicts'."
2.8 + """
2.9 + Update 'new_dict' with the contents of the set dictionary 'dicts'.
2.10 + None entries may be incorporated into object sets. For example:
2.11 +
2.12 + d1: {'a' : None}
2.13 + d2: {'a' : x}
2.14 + -> {'a' : {None, x}}
2.15 +
2.16 + Here, None might be used to represent an empty set and x may be an existing
2.17 + set.
2.18 + """
2.19
2.20 for old_dict in dicts:
2.21 for key, value in old_dict.items():
3.1 --- a/micropython/data.py Wed Feb 29 00:39:20 2012 +0100
3.2 +++ b/micropython/data.py Mon Mar 05 00:25:11 2012 +0100
3.3 @@ -418,6 +418,7 @@
3.4 # Visit each user and examine the attribute usage for each name.
3.5
3.6 for user in self.all_attribute_users:
3.7 + user._attrtypes = self._deduce_types(user._attrcombined, objtable)
3.8 self._finalise_contributor(user, objtable)
3.9
3.10 def _finalise_contributor(self, node, objtable):
3.11 @@ -428,22 +429,26 @@
3.12 """
3.13
3.14 if not hasattr(node, "_attrtypes"):
3.15 - node._attrtypes = self._deduce_types(node, objtable)
3.16 -
3.17 - for contributor in node._attrcontributors:
3.18 - self._finalise_contributor(contributor, objtable)
3.19 -
3.20 - def _deduce_types(self, user, objtable):
3.21 + merged = {}
3.22 + for user in node._attrdefs:
3.23 + merged.update(user._attrnames)
3.24 + node._attrmerged = combine_mapping_dicts(deepen_mapping_dict(node._attrnames), deepen_mapping_dict(merged))
3.25 + node._attrtypes = self._deduce_types(node._attrmerged, objtable)
3.26 +
3.27 + for contributor in node._attrbranches:
3.28 + self._finalise_contributor(contributor, objtable)
3.29 +
3.30 + def _deduce_types(self, usage, objtable):
3.31
3.32 """
3.33 - Deduce the types for names using attributes on the given 'user' node
3.34 - using the given 'objtable'.
3.35 + Deduce the types for names from the given attribute 'usage' and using
3.36 + the given 'objtable'.
3.37 """
3.38
3.39 attrtypes = {}
3.40 - for name, usage in user._attrcombined.items():
3.41 - if usage is not None:
3.42 - attrtypes[name] = get_object_types_for_usage(usage, objtable, name, self.full_name())
3.43 + for name, combined_usage in usage.items():
3.44 + if combined_usage is not None:
3.45 + attrtypes[name] = get_object_types_for_usage(combined_usage, objtable, name, self.full_name())
3.46 return attrtypes
3.47
3.48 def get_usage_from_contributors(self, node):
3.49 @@ -600,6 +605,7 @@
3.50
3.51 if not hasattr(node, "_attrnames"):
3.52 node._attrnames = {}
3.53 + node._attrmerged = {}
3.54
3.55 # Branches contributing usage to this node.
3.56
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/tests/attribute_usage_specific.py Mon Mar 05 00:25:11 2012 +0100
4.3 @@ -0,0 +1,23 @@
4.4 +#!/usr/bin/env python
4.5 +
4.6 +class A:
4.7 + def f(self, x):
4.8 + return 0
4.9 + def g(self, y):
4.10 + return 2
4.11 +
4.12 +class B:
4.13 + def g(self, z):
4.14 + return 4
4.15 +
4.16 +def f(x, y): # x : A, B
4.17 + result = x.g(1)
4.18 + while y: # x : A only
4.19 + y = x.f(1)
4.20 + return result
4.21 +
4.22 +a = A()
4.23 +b = B()
4.24 +result_2 = f(a, 1)
4.25 +
4.26 +# vim: tabstop=4 expandtab shiftwidth=4