1.1 --- a/micropython/deduce.py Mon Mar 10 23:14:26 2014 +0100
1.2 +++ b/micropython/deduce.py Thu Mar 13 23:10:25 2014 +0100
1.3 @@ -181,14 +181,8 @@
1.4 general definition-based type observations.
1.5 """
1.6
1.7 - targets = set()
1.8 target_names = self.possible_accessor_types_from_usage(node, defining_users)
1.9 -
1.10 - if target_names:
1.11 - for target_name, is_static in target_names:
1.12 - targets.add(self.objtable.get_object(target_name))
1.13 -
1.14 - return targets
1.15 + return self.get_targets_from_type_names(target_names)
1.16
1.17 def possible_accessors_for_attribute(self, attrname):
1.18
1.19 @@ -201,6 +195,21 @@
1.20
1.21 return targets
1.22
1.23 + def get_targets_from_type_names(self, target_names):
1.24 +
1.25 + """
1.26 + Given a collection of 'target_names' of the form (name, is_static),
1.27 + return a set of types for the 'name' part of each tuple.
1.28 + """
1.29 +
1.30 + targets = set()
1.31 +
1.32 + if target_names:
1.33 + for target_name, is_static in target_names:
1.34 + targets.add(self.objtable.get_object(target_name))
1.35 +
1.36 + return targets
1.37 +
1.38 # Visitor methods.
1.39
1.40 def _visitUnit(self, node):
1.41 @@ -238,11 +247,16 @@
1.42 node._guard_types = {}
1.43 node._guards = {}
1.44
1.45 - for name in node.unit.positional_names:
1.46 - # NOTE: Test for tuple parameters (see micropython.report.Report._parameters).
1.47 - # NOTE: No _values usage here because it is mostly useless information, except perhaps for defaults.
1.48 - attrtypes = node._attrtypes.get(name)
1.49 - self._visitGuardForNameDeduced(node, name, attrtypes)
1.50 + self._visitParameters(node, node.unit.positional_names)
1.51 +
1.52 + def _visitParameters(self, node, parameters):
1.53 + for name in parameters:
1.54 + if isinstance(name, tuple):
1.55 + self._visitParameters(node, name)
1.56 + else:
1.57 + # NOTE: No _values usage here because it is mostly useless information, except perhaps for defaults.
1.58 + types = self.get_targets_from_type_names(node._attrtypes.get(name))
1.59 + self._visitGuardForNameDeduced(node, name, types)
1.60
1.61 def _visitAttr(self, node):
1.62
1.63 @@ -532,14 +546,14 @@
1.64
1.65 # Need to check any concrete value against deductions.
1.66
1.67 - attrtypes = node._attrtypes.get(name)
1.68 + types = self.get_targets_from_type_names(node._attrtypes.get(name))
1.69 value = node._values.get(name)
1.70
1.71 # Where a concrete type conflicts with deductions, the usage of
1.72 # attributes cannot be supported and is thus impossible.
1.73
1.74 if value:
1.75 - if attrtypes and value not in attrtypes:
1.76 + if types and value not in types:
1.77 node._guard_types[name] = "impossible"
1.78 else:
1.79 node._guard_types[name] = "single"
1.80 @@ -547,19 +561,19 @@
1.81
1.82 # Where no concrete type is known, usage must be checked.
1.83
1.84 - elif attrtypes:
1.85 - self._visitGuardForNameDeduced(node, name, attrtypes)
1.86 + elif types:
1.87 + self._visitGuardForNameDeduced(node, name, types)
1.88
1.89 # Where no deductions are made, no guards are needed.
1.90
1.91 - def _visitGuardForNameDeduced(self, node, name, attrtypes):
1.92 - if not attrtypes:
1.93 + def _visitGuardForNameDeduced(self, node, name, types):
1.94 + if not types:
1.95 return
1.96 - if len(attrtypes) == 1:
1.97 + if len(types) == 1:
1.98 node._guard_types[name] = "single"
1.99 else:
1.100 node._guard_types[name] = "multiple"
1.101 - node._guards[name] = attrtypes
1.102 + node._guards[name] = types
1.103
1.104 def visitCallFunc(self, node):
1.105