micropython

Changeset

556:875b09b3d355
2012-06-28 Paul Boddie raw files shortlog changelog graph Removed usage gathering for module globals by introducing Module-specific methods. Added _attr annotations for attribute accessors, using them in reports via the possible_accessor_types ASTVisitor method. Fixed imports in the common module.
docs/annotations.txt (file) micropython/common.py (file) micropython/data.py (file) micropython/inspect.py (file)
     1.1 --- a/docs/annotations.txt	Wed Jun 27 01:32:38 2012 +0200
     1.2 +++ b/docs/annotations.txt	Thu Jun 28 22:58:02 2012 +0200
     1.3 @@ -3,6 +3,12 @@
     1.4  
     1.5  These annotations should be defined in the revised compiler.ast classes.
     1.6  
     1.7 +Evaluation Results
     1.8 +------------------
     1.9 +
    1.10 +_attr               notes the result associated with an attribute access
    1.11 +                    operation during inspection
    1.12 +
    1.13  Attribute Users
    1.14  ---------------
    1.15  
     2.1 --- a/micropython/common.py	Wed Jun 27 01:32:38 2012 +0200
     2.2 +++ b/micropython/common.py	Thu Jun 28 22:58:02 2012 +0200
     2.3 @@ -19,7 +19,8 @@
     2.4  this program.  If not, see <http://www.gnu.org/licenses/>.
     2.5  """
     2.6  
     2.7 -from micropython.basicdata import Instance
     2.8 +from micropython.data import Attr, Instance
     2.9 +from micropython.errors import *
    2.10  import sys
    2.11  
    2.12  # Visitors and activities related to node annotations.
    2.13 @@ -69,7 +70,14 @@
    2.14  
    2.15          target_names = set()
    2.16  
    2.17 -        if hasattr(node, "_attrusers"):
    2.18 +        if hasattr(node, "_attr") and not isinstance(node._attr, Instance):
    2.19 +            attr = node._attr
    2.20 +            if isinstance(attr, Attr):
    2.21 +                target_names.add((attr.parent.full_name(), attr.is_static_attribute()))
    2.22 +            else:
    2.23 +                target_names.add((attr.full_name(), attr.is_static_attribute()))
    2.24 +
    2.25 +        elif hasattr(node, "_attrusers"):
    2.26  
    2.27              # Visit each attribute user.
    2.28  
     3.1 --- a/micropython/data.py	Wed Jun 27 01:32:38 2012 +0200
     3.2 +++ b/micropython/data.py	Thu Jun 28 22:58:02 2012 +0200
     3.3 @@ -685,6 +685,16 @@
     3.4          if not hasattr(node, "_attrdefs"):
     3.5              node._attrdefs = []
     3.6  
     3.7 +    def _define_attribute_accessor(self, name, attrname, node, value):
     3.8 +
     3.9 +        # NOTE: Revisiting of nodes may occur for loops.
    3.10 +
    3.11 +        if not hasattr(node, "_attrusers"):
    3.12 +            node._attrusers = set()
    3.13 +
    3.14 +        node._attrusers.update(self.use_attribute(name, attrname, value))
    3.15 +        node._username = name
    3.16 +
    3.17      # Branch management methods.
    3.18  
    3.19      def _new_branchpoint(self, loop_node=None):
    3.20 @@ -2043,6 +2053,26 @@
    3.21  
    3.22          return dict(self)
    3.23  
    3.24 +    # Attribute usage methods that do not apply to module globals.
    3.25 +
    3.26 +    def _define_attribute_user(self, node):
    3.27 +        pass
    3.28 +
    3.29 +    def _use_attribute(self, name, attrname, value=None):
    3.30 +
    3.31 +        """
    3.32 +        Record usage for 'name' of 'attrname' (and optional assignment 'value')
    3.33 +        by recording general name usage.
    3.34 +        """
    3.35 +
    3.36 +        self.importer.use_name(attrname, self.full_name(), value)
    3.37 +
    3.38 +    def _init_attribute_user(self, node):
    3.39 +        pass
    3.40 +
    3.41 +    def _define_attribute_accessor(self, name, attrname, node, value):
    3.42 +        pass
    3.43 +
    3.44  # Pre-made instances.
    3.45  
    3.46  type_class = TypeClass("type") # details to be filled in later
     4.1 --- a/micropython/inspect.py	Wed Jun 27 01:32:38 2012 +0200
     4.2 +++ b/micropython/inspect.py	Thu Jun 28 22:58:02 2012 +0200
     4.3 @@ -457,6 +457,16 @@
     4.4  
     4.5          return self.get_namespace()._use_specific_attribute(objname, attrname, from_name)
     4.6  
     4.7 +    def define_attribute_accessor(self, name, attrname, node, value=None):
     4.8 +
     4.9 +        """
    4.10 +        Note applicable attribute users providing the given 'name' when
    4.11 +        accessing the given 'attrname' on the specified 'node', with the
    4.12 +        optional 'value' indicating an assignment. 
    4.13 +        """
    4.14 +
    4.15 +        self.get_namespace()._define_attribute_accessor(name, attrname, node, value)
    4.16 +
    4.17      # Visitor methods.
    4.18  
    4.19      def default(self, node, *args):
    4.20 @@ -588,14 +598,7 @@
    4.21          # independently of the namespace).
    4.22  
    4.23          if expr.parent is self.get_namespace() and not self.get_namespace() is self:
    4.24 -
    4.25 -            # NOTE: Revisiting of nodes may occur for loops.
    4.26 -
    4.27 -            if not hasattr(node, "_attrusers"):
    4.28 -                node._attrusers = set()
    4.29 -
    4.30 -            node._attrusers.update(self.use_attribute(expr.name, attrname, value))
    4.31 -            node._username = expr.name
    4.32 +            self.define_attribute_accessor(expr.name, attrname, node, value)
    4.33          else:
    4.34              self.use_name(attrname, node.expr, value)
    4.35  
    4.36 @@ -715,7 +718,7 @@
    4.37  
    4.38              if expr.name == "self":
    4.39                  self.store_instance_attr(attrname)
    4.40 -                self.use_attribute(expr.name, attrname, value) # NOTE: Impose constraints on the type given the hierarchy.
    4.41 +                self.use_attribute(expr.name, attrname, value)
    4.42                  self._visitAttrUser(expr, attrname, node, self.expr)
    4.43  
    4.44              elif isinstance(value, Module):
    4.45 @@ -1039,7 +1042,8 @@
    4.46      def visitGetattr(self, node):
    4.47          expr = self.dispatch(node.expr)
    4.48          attrname = node.attrname
    4.49 -        return self._visitAttr(expr, attrname, node)
    4.50 +        node._attr = self._visitAttr(expr, attrname, node)
    4.51 +        return node._attr
    4.52  
    4.53      def visitGlobal(self, node):
    4.54          if self.namespaces: