# HG changeset patch # User Paul Boddie # Date 1386518200 -3600 # Node ID c20f8d7fe5a4d0fd34b06079a2d93a47607527d4 # Parent fe0c7e0224b51c679ff1a686cb4ed588c71c70ad Moved deduction-related methods to the deduction module. diff -r fe0c7e0224b5 -r c20f8d7fe5a4 micropython/common.py --- a/micropython/common.py Sun Dec 08 01:41:43 2013 +0100 +++ b/micropython/common.py Sun Dec 08 16:56:40 2013 +0100 @@ -20,9 +20,8 @@ """ from micropython.stdcompiler import compiler -from compiler.ast import AssAttr, Getattr, Name -from micropython.basicdata import Const, Constant, TypedInstance -from micropython.data import BaseAttr, Class, Module +from micropython.basicdata import Constant, TypedInstance +from micropython.data import BaseAttr, Class from micropython.errors import * from os.path import split @@ -79,8 +78,6 @@ exc.unit_name = self.get_unit().full_name() raise - # Deduction-related methods. - def get_attributes(self, targets, attrname): "Return a list of attributes for 'targets' supporting 'attrname'." @@ -111,129 +108,6 @@ return None - def provides_constant_result(self, value): - - "Return whether 'value' provides a constant result." - - return isinstance(value, (Const, Constant)) - - def provides_self_access(self, expr, unit): - - """ - Return whether the 'expr' in the given 'unit' provides a self-based - attribute access. - """ - - attr_value = self.get_attribute_and_value(expr) - - if attr_value: - target, value = attr_value - - return target and target.name == "self" and target.parent is unit and \ - unit.is_method() - - return False - - def possible_attributes_from_annotation(self, expr, attr, attrname): - - """ - Return (attribute, value) details provided by the 'expr' or 'attr' - annotations on a node for an access involving 'attrname'. - """ - - attr_value = self.get_attribute_and_value(attr) - - if attr_value: - return [attr_value] - - attrs = set() - - if expr: - - # Permitting multiple expression types if they provide the - # attribute. - - if isinstance(expr, BaseAttr): - exprs = expr.get_values() - else: - exprs = [expr] - - # For each expression value try and get a concrete - # attribute. - - for expr in exprs: - found_attr = expr.all_attributes().get(attrname) - - # Where an attribute can be obtained, record its - # details. - - if found_attr: - attrs.add((found_attr, found_attr.get_value())) - - return attrs - - def possible_accessor_types_from_usage(self, node, defining_users=1): - - """ - Return a set of (target name, static) tuples from an investigation of - attribute usage observations stored on the given 'node'. - - If 'defining_users' is set to a false value, attempt to get the type - names specifically applicable to the node, rather than retrieving more - general definition-based type observations. - """ - - target_names = set() - - if node._attrusers: - - # Visit each attribute user. - - for user in node._attrusers: - - # Since users such as branches may not provide type information, - # attempt to find defining users. - - if defining_users: - for def_user in user._attrdefs or [user]: - for target_name, is_static in def_user._attrtypes.get(node._username, []): - target_names.add((target_name, is_static)) - else: - for target_name, is_static in user._attrspecifictypes.get(node._username, []): - target_names.add((target_name, is_static)) - - return target_names - - def possible_accessors_from_usage(self, node, defining_users=1): - - """ - Return possible accessors from the usage recorded on the given 'node'. - - If 'defining_users' is set to a false value, attempt to get the type - names specifically applicable to the node, rather than retrieving more - general definition-based type observations. - """ - - targets = set() - target_names = self.possible_accessor_types_from_usage(node, defining_users) - - if target_names: - for target_name, is_static in target_names: - targets.add(self.objtable.get_object(target_name)) - - return targets - - def possible_accessors_for_attribute(self, attrname): - - "Return possible accessors given the single 'attrname'." - - targets = set() - - for target_name in self.objtable.any_possible_objects([attrname]): - targets.add(self.objtable.get_object(target_name)) - - return targets - def get_module_name(node, module): """ diff -r fe0c7e0224b5 -r c20f8d7fe5a4 micropython/deduce.py --- a/micropython/deduce.py Sun Dec 08 01:41:43 2013 +0100 +++ b/micropython/deduce.py Sun Dec 08 16:56:40 2013 +0100 @@ -19,10 +19,19 @@ this program. If not, see . """ -from micropython.common import * +from micropython.stdcompiler import compiler +from compiler.ast import AssAttr, Getattr, Name + +from micropython.basicdata import Const, Constant, TypedInstance +from micropython.common import ASTVisitor, used_by_unit from micropython.data import * from micropython.errors import * +try: + set +except NameError: + from sets import Set as set + # Source code classes. class DeducedSource(ASTVisitor): @@ -57,10 +66,143 @@ return node.visit(self.visitor, *args) except AttributeError: # NOTE: Obligatory hack to find real attribute errors. - if isinstance(node, (Getattr, AssAttr)): - raise + #if isinstance(node, self.implemented_nodes): + # raise return self.visitor.default(node, *args) + #implemented_nodes = ( + # AssAttr, Assign, AssName, AssList, AssTuple, CallFunc, Getattr, + # Add, Bitand, Bitor, Bitxor, Div, FloorDiv, Invert, LeftShift, Mod, Mul, + # Power, RightShift, Sub, UnaryAdd, UnarySub + # ) + + # Deduction-related methods. + + def provides_constant_result(self, value): + + "Return whether 'value' provides a constant result." + + return isinstance(value, (Const, Constant)) + + def provides_self_access(self, expr, unit): + + """ + Return whether the 'expr' in the given 'unit' provides a self-based + attribute access. + """ + + attr_value = self.get_attribute_and_value(expr) + + if attr_value: + target, value = attr_value + + return target and target.name == "self" and target.parent is unit and \ + unit.is_method() + + return False + + def possible_attributes_from_annotation(self, expr, attr, attrname): + + """ + Return (attribute, value) details provided by the 'expr' or 'attr' + annotations on a node for an access involving 'attrname'. + """ + + attr_value = self.get_attribute_and_value(attr) + + if attr_value: + return [attr_value] + + attrs = set() + + if expr: + + # Permitting multiple expression types if they provide the + # attribute. + + if isinstance(expr, BaseAttr): + exprs = expr.get_values() + else: + exprs = [expr] + + # For each expression value try and get a concrete + # attribute. + + for expr in exprs: + found_attr = expr.all_attributes().get(attrname) + + # Where an attribute can be obtained, record its + # details. + + if found_attr: + attrs.add((found_attr, found_attr.get_value())) + + return attrs + + def possible_accessor_types_from_usage(self, node, defining_users=1): + + """ + Return a set of (target name, static) tuples from an investigation of + attribute usage observations stored on the given 'node'. + + If 'defining_users' is set to a false value, attempt to get the type + names specifically applicable to the node, rather than retrieving more + general definition-based type observations. + """ + + target_names = set() + + if node._attrusers: + + # Visit each attribute user. + + for user in node._attrusers: + + # Since users such as branches may not provide type information, + # attempt to find defining users. + + if defining_users: + for def_user in user._attrdefs or [user]: + for target_name, is_static in def_user._attrtypes.get(node._username, []): + target_names.add((target_name, is_static)) + else: + for target_name, is_static in user._attrspecifictypes.get(node._username, []): + target_names.add((target_name, is_static)) + + return target_names + + def possible_accessors_from_usage(self, node, defining_users=1): + + """ + Return possible accessors from the usage recorded on the given 'node'. + + If 'defining_users' is set to a false value, attempt to get the type + names specifically applicable to the node, rather than retrieving more + general definition-based type observations. + """ + + targets = set() + target_names = self.possible_accessor_types_from_usage(node, defining_users) + + if target_names: + for target_name, is_static in target_names: + targets.add(self.objtable.get_object(target_name)) + + return targets + + def possible_accessors_for_attribute(self, attrname): + + "Return possible accessors given the single 'attrname'." + + targets = set() + + for target_name in self.objtable.any_possible_objects([attrname]): + targets.add(self.objtable.get_object(target_name)) + + return targets + + # Visitor methods. + def _visitUnit(self, node): """