# HG changeset patch # User Paul Boddie # Date 1395092450 -3600 # Node ID 43ab2c323dcfbde2d12eec7a48e3d2100123179c # Parent 78f31936f4e19bf4dfcfa2510e690cc1dda9775c Supported nested invocations; handled unusable values when deducing attributes. Refuse to produce guards without any usable deductions. diff -r 78f31936f4e1 -r 43ab2c323dcf micropython/deduce.py --- a/micropython/deduce.py Mon Mar 17 22:37:22 2014 +0100 +++ b/micropython/deduce.py Mon Mar 17 22:40:50 2014 +0100 @@ -125,11 +125,13 @@ else: exprs = [expr] - # For each expression value try and get a concrete - # attribute. + # For each expression value try and get a concrete attribute. - for expr in exprs: - found_attr = expr.all_attributes().get(attrname) + for _expr in exprs: + if isinstance(_expr, Instance): + continue + + found_attr = _expr.all_attributes().get(attrname) # Where an attribute can be obtained, record its # details. @@ -283,6 +285,10 @@ node._access_attrs = attributes + # Return the _attr annotation for instantiation detection. + + return node._attr + def _annotateAttr(self, node, target, attrname): """ @@ -540,7 +546,7 @@ value = attr if value and isinstance(value, Instance) and not isinstance(value, TypedInstance): - node._values[node.name] = expr + node._values[node.name] = expr or make_instance() self._visitGuard(node) @@ -554,6 +560,10 @@ "Make an annotation stating the acceptable types for a name." # Need to check any concrete value against deductions. + # Where no local observations exist, no guard can usefully be asserted. + + if not node._attrtypes and not node._values: + return types = self.get_targets_from_type_names(node._attrtypes.get(name)) value = node._values.get(name) @@ -588,17 +598,18 @@ "Identify any concrete types involved with instantiation." - for n in node.getChildNodes(): + for n in node.getChildNodes()[1:]: # ignore node.node self.dispatch(n) # Determine whether the target of the invocation refers to a class. - attr = node.node._attr + attr = self.dispatch(node.node) - if attr and not isinstance(attr, Instance): - value = attr.get_value() - if value and isinstance(value, Class): - return TypedInstance(value) + if attr: + if not isinstance(attr, (Instance, UnresolvedName)): + value = attr.get_value() + if value and isinstance(value, Class): + return TypedInstance(value) def _visitOperator(self, node):