1.1 --- a/micropython/common.py Sun Dec 08 01:41:43 2013 +0100
1.2 +++ b/micropython/common.py Sun Dec 08 16:56:40 2013 +0100
1.3 @@ -20,9 +20,8 @@
1.4 """
1.5
1.6 from micropython.stdcompiler import compiler
1.7 -from compiler.ast import AssAttr, Getattr, Name
1.8 -from micropython.basicdata import Const, Constant, TypedInstance
1.9 -from micropython.data import BaseAttr, Class, Module
1.10 +from micropython.basicdata import Constant, TypedInstance
1.11 +from micropython.data import BaseAttr, Class
1.12 from micropython.errors import *
1.13 from os.path import split
1.14
1.15 @@ -79,8 +78,6 @@
1.16 exc.unit_name = self.get_unit().full_name()
1.17 raise
1.18
1.19 - # Deduction-related methods.
1.20 -
1.21 def get_attributes(self, targets, attrname):
1.22
1.23 "Return a list of attributes for 'targets' supporting 'attrname'."
1.24 @@ -111,129 +108,6 @@
1.25
1.26 return None
1.27
1.28 - def provides_constant_result(self, value):
1.29 -
1.30 - "Return whether 'value' provides a constant result."
1.31 -
1.32 - return isinstance(value, (Const, Constant))
1.33 -
1.34 - def provides_self_access(self, expr, unit):
1.35 -
1.36 - """
1.37 - Return whether the 'expr' in the given 'unit' provides a self-based
1.38 - attribute access.
1.39 - """
1.40 -
1.41 - attr_value = self.get_attribute_and_value(expr)
1.42 -
1.43 - if attr_value:
1.44 - target, value = attr_value
1.45 -
1.46 - return target and target.name == "self" and target.parent is unit and \
1.47 - unit.is_method()
1.48 -
1.49 - return False
1.50 -
1.51 - def possible_attributes_from_annotation(self, expr, attr, attrname):
1.52 -
1.53 - """
1.54 - Return (attribute, value) details provided by the 'expr' or 'attr'
1.55 - annotations on a node for an access involving 'attrname'.
1.56 - """
1.57 -
1.58 - attr_value = self.get_attribute_and_value(attr)
1.59 -
1.60 - if attr_value:
1.61 - return [attr_value]
1.62 -
1.63 - attrs = set()
1.64 -
1.65 - if expr:
1.66 -
1.67 - # Permitting multiple expression types if they provide the
1.68 - # attribute.
1.69 -
1.70 - if isinstance(expr, BaseAttr):
1.71 - exprs = expr.get_values()
1.72 - else:
1.73 - exprs = [expr]
1.74 -
1.75 - # For each expression value try and get a concrete
1.76 - # attribute.
1.77 -
1.78 - for expr in exprs:
1.79 - found_attr = expr.all_attributes().get(attrname)
1.80 -
1.81 - # Where an attribute can be obtained, record its
1.82 - # details.
1.83 -
1.84 - if found_attr:
1.85 - attrs.add((found_attr, found_attr.get_value()))
1.86 -
1.87 - return attrs
1.88 -
1.89 - def possible_accessor_types_from_usage(self, node, defining_users=1):
1.90 -
1.91 - """
1.92 - Return a set of (target name, static) tuples from an investigation of
1.93 - attribute usage observations stored on the given 'node'.
1.94 -
1.95 - If 'defining_users' is set to a false value, attempt to get the type
1.96 - names specifically applicable to the node, rather than retrieving more
1.97 - general definition-based type observations.
1.98 - """
1.99 -
1.100 - target_names = set()
1.101 -
1.102 - if node._attrusers:
1.103 -
1.104 - # Visit each attribute user.
1.105 -
1.106 - for user in node._attrusers:
1.107 -
1.108 - # Since users such as branches may not provide type information,
1.109 - # attempt to find defining users.
1.110 -
1.111 - if defining_users:
1.112 - for def_user in user._attrdefs or [user]:
1.113 - for target_name, is_static in def_user._attrtypes.get(node._username, []):
1.114 - target_names.add((target_name, is_static))
1.115 - else:
1.116 - for target_name, is_static in user._attrspecifictypes.get(node._username, []):
1.117 - target_names.add((target_name, is_static))
1.118 -
1.119 - return target_names
1.120 -
1.121 - def possible_accessors_from_usage(self, node, defining_users=1):
1.122 -
1.123 - """
1.124 - Return possible accessors from the usage recorded on the given 'node'.
1.125 -
1.126 - If 'defining_users' is set to a false value, attempt to get the type
1.127 - names specifically applicable to the node, rather than retrieving more
1.128 - general definition-based type observations.
1.129 - """
1.130 -
1.131 - targets = set()
1.132 - target_names = self.possible_accessor_types_from_usage(node, defining_users)
1.133 -
1.134 - if target_names:
1.135 - for target_name, is_static in target_names:
1.136 - targets.add(self.objtable.get_object(target_name))
1.137 -
1.138 - return targets
1.139 -
1.140 - def possible_accessors_for_attribute(self, attrname):
1.141 -
1.142 - "Return possible accessors given the single 'attrname'."
1.143 -
1.144 - targets = set()
1.145 -
1.146 - for target_name in self.objtable.any_possible_objects([attrname]):
1.147 - targets.add(self.objtable.get_object(target_name))
1.148 -
1.149 - return targets
1.150 -
1.151 def get_module_name(node, module):
1.152
1.153 """
2.1 --- a/micropython/deduce.py Sun Dec 08 01:41:43 2013 +0100
2.2 +++ b/micropython/deduce.py Sun Dec 08 16:56:40 2013 +0100
2.3 @@ -19,10 +19,19 @@
2.4 this program. If not, see <http://www.gnu.org/licenses/>.
2.5 """
2.6
2.7 -from micropython.common import *
2.8 +from micropython.stdcompiler import compiler
2.9 +from compiler.ast import AssAttr, Getattr, Name
2.10 +
2.11 +from micropython.basicdata import Const, Constant, TypedInstance
2.12 +from micropython.common import ASTVisitor, used_by_unit
2.13 from micropython.data import *
2.14 from micropython.errors import *
2.15
2.16 +try:
2.17 + set
2.18 +except NameError:
2.19 + from sets import Set as set
2.20 +
2.21 # Source code classes.
2.22
2.23 class DeducedSource(ASTVisitor):
2.24 @@ -57,10 +66,143 @@
2.25 return node.visit(self.visitor, *args)
2.26 except AttributeError:
2.27 # NOTE: Obligatory hack to find real attribute errors.
2.28 - if isinstance(node, (Getattr, AssAttr)):
2.29 - raise
2.30 + #if isinstance(node, self.implemented_nodes):
2.31 + # raise
2.32 return self.visitor.default(node, *args)
2.33
2.34 + #implemented_nodes = (
2.35 + # AssAttr, Assign, AssName, AssList, AssTuple, CallFunc, Getattr,
2.36 + # Add, Bitand, Bitor, Bitxor, Div, FloorDiv, Invert, LeftShift, Mod, Mul,
2.37 + # Power, RightShift, Sub, UnaryAdd, UnarySub
2.38 + # )
2.39 +
2.40 + # Deduction-related methods.
2.41 +
2.42 + def provides_constant_result(self, value):
2.43 +
2.44 + "Return whether 'value' provides a constant result."
2.45 +
2.46 + return isinstance(value, (Const, Constant))
2.47 +
2.48 + def provides_self_access(self, expr, unit):
2.49 +
2.50 + """
2.51 + Return whether the 'expr' in the given 'unit' provides a self-based
2.52 + attribute access.
2.53 + """
2.54 +
2.55 + attr_value = self.get_attribute_and_value(expr)
2.56 +
2.57 + if attr_value:
2.58 + target, value = attr_value
2.59 +
2.60 + return target and target.name == "self" and target.parent is unit and \
2.61 + unit.is_method()
2.62 +
2.63 + return False
2.64 +
2.65 + def possible_attributes_from_annotation(self, expr, attr, attrname):
2.66 +
2.67 + """
2.68 + Return (attribute, value) details provided by the 'expr' or 'attr'
2.69 + annotations on a node for an access involving 'attrname'.
2.70 + """
2.71 +
2.72 + attr_value = self.get_attribute_and_value(attr)
2.73 +
2.74 + if attr_value:
2.75 + return [attr_value]
2.76 +
2.77 + attrs = set()
2.78 +
2.79 + if expr:
2.80 +
2.81 + # Permitting multiple expression types if they provide the
2.82 + # attribute.
2.83 +
2.84 + if isinstance(expr, BaseAttr):
2.85 + exprs = expr.get_values()
2.86 + else:
2.87 + exprs = [expr]
2.88 +
2.89 + # For each expression value try and get a concrete
2.90 + # attribute.
2.91 +
2.92 + for expr in exprs:
2.93 + found_attr = expr.all_attributes().get(attrname)
2.94 +
2.95 + # Where an attribute can be obtained, record its
2.96 + # details.
2.97 +
2.98 + if found_attr:
2.99 + attrs.add((found_attr, found_attr.get_value()))
2.100 +
2.101 + return attrs
2.102 +
2.103 + def possible_accessor_types_from_usage(self, node, defining_users=1):
2.104 +
2.105 + """
2.106 + Return a set of (target name, static) tuples from an investigation of
2.107 + attribute usage observations stored on the given 'node'.
2.108 +
2.109 + If 'defining_users' is set to a false value, attempt to get the type
2.110 + names specifically applicable to the node, rather than retrieving more
2.111 + general definition-based type observations.
2.112 + """
2.113 +
2.114 + target_names = set()
2.115 +
2.116 + if node._attrusers:
2.117 +
2.118 + # Visit each attribute user.
2.119 +
2.120 + for user in node._attrusers:
2.121 +
2.122 + # Since users such as branches may not provide type information,
2.123 + # attempt to find defining users.
2.124 +
2.125 + if defining_users:
2.126 + for def_user in user._attrdefs or [user]:
2.127 + for target_name, is_static in def_user._attrtypes.get(node._username, []):
2.128 + target_names.add((target_name, is_static))
2.129 + else:
2.130 + for target_name, is_static in user._attrspecifictypes.get(node._username, []):
2.131 + target_names.add((target_name, is_static))
2.132 +
2.133 + return target_names
2.134 +
2.135 + def possible_accessors_from_usage(self, node, defining_users=1):
2.136 +
2.137 + """
2.138 + Return possible accessors from the usage recorded on the given 'node'.
2.139 +
2.140 + If 'defining_users' is set to a false value, attempt to get the type
2.141 + names specifically applicable to the node, rather than retrieving more
2.142 + general definition-based type observations.
2.143 + """
2.144 +
2.145 + targets = set()
2.146 + target_names = self.possible_accessor_types_from_usage(node, defining_users)
2.147 +
2.148 + if target_names:
2.149 + for target_name, is_static in target_names:
2.150 + targets.add(self.objtable.get_object(target_name))
2.151 +
2.152 + return targets
2.153 +
2.154 + def possible_accessors_for_attribute(self, attrname):
2.155 +
2.156 + "Return possible accessors given the single 'attrname'."
2.157 +
2.158 + targets = set()
2.159 +
2.160 + for target_name in self.objtable.any_possible_objects([attrname]):
2.161 + targets.add(self.objtable.get_object(target_name))
2.162 +
2.163 + return targets
2.164 +
2.165 + # Visitor methods.
2.166 +
2.167 def _visitUnit(self, node):
2.168
2.169 """