1.1 --- a/micropython/data.py Sun Feb 14 23:49:17 2010 +0100
1.2 +++ b/micropython/data.py Mon Feb 15 01:35:17 2010 +0100
1.3 @@ -483,6 +483,10 @@
1.4
1.5 self.speculative_shelves[-1].append(speculative)
1.6
1.7 + # NOTE: Could record contributing usage as speculative usage.
1.8 +
1.9 + #self.speculative_shelves[-1].append(usage)
1.10 +
1.11 # Forget about any nodes which defined names employing attributes in
1.12 # this branch if the branch is abandoned.
1.13
1.14 @@ -564,7 +568,13 @@
1.15
1.16 for shelved_users in self.user_shelves.pop():
1.17 for name, nodes in shelved_users.items():
1.18 - users[name].update(nodes)
1.19 +
1.20 + # Handle cases where the name is not known at this level.
1.21 +
1.22 + if users.has_key(name):
1.23 + users[name].update(nodes)
1.24 + else:
1.25 + users[name] = nodes
1.26
1.27 # Where each shelved set of definitions is a superset of the eventual
1.28 # definitions for a name, record these specialised sets of usage.
2.1 --- a/micropython/trans.py Sun Feb 14 23:49:17 2010 +0100
2.2 +++ b/micropython/trans.py Mon Feb 15 01:35:17 2010 +0100
2.3 @@ -319,7 +319,7 @@
2.4
2.5 if node._alternative_attrnames.has_key(name):
2.6 all_names_used = set()
2.7 - all_names_used.update(node._alternative_attrnames)
2.8 + all_names_used.update(node._alternative_attrnames[name])
2.9 all_names_used.add(tuple(names_used))
2.10 else:
2.11 all_names_used = [names_used]
2.12 @@ -327,14 +327,31 @@
2.13 # Get the names of all object types supporting these names.
2.14
2.15 targets = set()
2.16 + common_targets = None
2.17 +
2.18 for names_used in all_names_used:
2.19 - targets.update(self.objtable.all_possible_objects_plus_status(names_used))
2.20 + found_targets = self.objtable.all_possible_objects_plus_status(names_used)
2.21 + found_target_names = [target_name for (target_name, is_static) in found_targets]
2.22 + targets.update(found_targets)
2.23 +
2.24 + if common_targets is None:
2.25 + common_targets = set(found_target_names)
2.26 + else:
2.27 + common_targets.intersection_update(found_target_names)
2.28 +
2.29 + # Report cases where no common targets can be found.
2.30 +
2.31 + if not common_targets:
2.32 + raise TranslateError(self.module.full_name(), node, "No common types found for expected attribute usage.")
2.33 +
2.34 + # NOTE: Need to merge targets using the same type but suggesting
2.35 + # NOTE: different kinds of attributes.
2.36
2.37 # Where only one object type is suggested, produce a guard.
2.38 # NOTE: This only supports classes as types, not modules.
2.39
2.40 if len(targets) == 1:
2.41 - target_name, is_static = targets[0]
2.42 + target_name, is_static = list(targets)[0]
2.43
2.44 # Access the object table to get the attribute.
2.45 # NOTE: This depends on the special entry in the table
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/tests/attribute_access_type_restriction_multiple_candidates.py Mon Feb 15 01:35:17 2010 +0100
3.3 @@ -0,0 +1,34 @@
3.4 +#!/usr/bin/env python
3.5 +
3.6 +"""
3.7 +This test attempts to cause the recording of the usage of 'C' in the function
3.8 +'f', alongside the expectation that 'D' might be used instead. A guard
3.9 +stipulating constraints for all of 'f' cannot therefore be generated. Meanwhile,
3.10 +the method 'E.h' should be eliminated.
3.11 +"""
3.12 +
3.13 +class C:
3.14 + def f(self):
3.15 + return 1
3.16 +
3.17 +class D:
3.18 + def g(self):
3.19 + return 2
3.20 +
3.21 +class E:
3.22 + def h(self): # unused
3.23 + return 3
3.24 +
3.25 +def f(c):
3.26 + if 1:
3.27 + if 1:
3.28 + x = c.f()
3.29 + return x
3.30 + return c.g()
3.31 +
3.32 +c = C()
3.33 +d = D()
3.34 +e = E()
3.35 +result1_1 = f(c)
3.36 +
3.37 +# vim: tabstop=4 expandtab shiftwidth=4