# HG changeset patch # User Paul Boddie # Date 1342301263 -7200 # Node ID 147cafbfea7705f2a03b31d12d4b65d8eaa46deb # Parent 264711a70b34fc9bbe44cca83e79f7c5ec2afcce Added _attr annotation to AssAttr and _expr annotation to AssAttr and Getattr. Added usage of _expr annotations to obtain details of attributes not identifiable during inspection (such as superclass attributes). diff -r 264711a70b34 -r 147cafbfea77 micropython/common.py --- a/micropython/common.py Sat Jul 14 21:46:38 2012 +0200 +++ b/micropython/common.py Sat Jul 14 23:27:43 2012 +0200 @@ -19,8 +19,9 @@ this program. If not, see . """ -from compiler.ast import Class, Function, Module, AssAttr, Getattr, Name -from micropython.data import Attr +from compiler.ast import AssAttr, Getattr, Name +import compiler.ast +from micropython.data import Attr, Class, Module from micropython.errors import * try: @@ -55,7 +56,7 @@ # NOTE: Should perhaps specialise the subclasses appropriately. - if isinstance(self, (Class, Function, Module)): + if isinstance(self, (compiler.ast.Class, compiler.ast.Function, compiler.ast.Module)): exc.unit_name = self.unit.full_name() else: exc.unit_name = self.full_name() @@ -81,13 +82,35 @@ if isinstance(node, (AssAttr, Getattr, Name)): + # Use any explicit attribute annotation. + if isinstance(node._attr, Attr): attr = node._attr target_names.add((attr.parent.full_name(), attr.is_static_attribute())) + return target_names + + # Otherwise, try and use an expression annotation. + + if isinstance(node, (AssAttr, Getattr)): + expr = node._expr + + if isinstance(expr, Attr) and expr.get_value(): + expr = expr.get_value() + + if isinstance(expr, Class): + attr = expr.all_class_attributes().get(node.attrname) + elif isinstance(expr, Module): + attr = expr.get(node.attrname) + else: + attr = None + + if attr: + target_names.add((attr.parent.full_name(), attr.is_static_attribute())) + return target_names # Otherwise, attempt to employ the attribute usage observations. - elif node._attrusers: + if node._attrusers: # Visit each attribute user. diff -r 264711a70b34 -r 147cafbfea77 micropython/inspect.py --- a/micropython/inspect.py Sat Jul 14 21:46:38 2012 +0200 +++ b/micropython/inspect.py Sat Jul 14 23:27:43 2012 +0200 @@ -840,19 +840,30 @@ self.use_attribute(expr.name, attrname, value) self._visitAttrUser(expr, attrname, node, self.expr) + # No definite attribute can be identified, since the instance + # being accessed may be a subclass of the method's class. + + attr = make_instance() + elif isinstance(value, Module): self.store_module_attr(attrname, value) + attr = value.get(attrname) elif isinstance(value, Class): self.store_class_attr(attrname, value) + attr = value.get(attrname) # Note usage of the attribute where a local is involved. else: self._visitAttrUser(expr, attrname, node, self.expr) + attr = make_instance() else: self.use_name(attrname, node) + attr = make_instance() + + node._attr = attr def visitAssList(self, node): @@ -1155,9 +1166,8 @@ visitGenExprInner = NOP def visitGetattr(self, node): - expr = self.dispatch(node.expr) - attrname = node.attrname - node._attr = self._visitAttr(expr, attrname, node) + node._expr = self.dispatch(node.expr) + node._attr = self._visitAttr(node._expr, node.attrname, node) return node._attr def visitGlobal(self, node):