1.1 --- a/docs/annotations.txt Mon Feb 27 23:22:33 2012 +0100
1.2 +++ b/docs/annotations.txt Wed Feb 29 00:39:20 2012 +0100
1.3 @@ -4,27 +4,31 @@
1.4 Attribute Users
1.5 ---------------
1.6
1.7 -_attrnames defines a dictionary mapping local names to sets of attribute
1.8 - names found to be used with those names in a branch
1.9 -_attrcombined defines a dictionary mapping local names to sets of attribute
1.10 - names found to be used with those names for the entire lifetime
1.11 - of a particular attribute user
1.12 -_attrtypes defines types deduced from the combined attribute usage details
1.13 -_attrdefs defines definition-related users which consume usage details
1.14 - from the node
1.15 +_attrnames defines a dictionary mapping local names to sets of
1.16 + attribute names found to be used with those names in a
1.17 + branch
1.18 +_attrcontributors defines nodes contributing to combined attribute usage known
1.19 + to a node
1.20 +_attrcombined defines a dictionary mapping local names to sets of
1.21 + attribute names found to be used with those names for the
1.22 + entire lifetime of a particular attribute user
1.23 +_attrtypes defines types deduced from the combined attribute usage
1.24 + details
1.25 +_attrdefs defines definition-related users which consume usage details
1.26 + from the node
1.27
1.28 Attribute Accessors
1.29 -------------------
1.30
1.31 -_attrusers defines a dictionary mapping local names to sets of nodes
1.32 - defining those names
1.33 +_attrusers defines a dictionary mapping local names to sets of nodes
1.34 + defining those names
1.35
1.36 Name Accessors
1.37 --------------
1.38
1.39 -_scope set as "constant", "local", "global" or "builtins"
1.40 +_scope set as "constant", "local", "global" or "builtins"
1.41
1.42 Program Units
1.43 -------------
1.44
1.45 -unit refers to a micropython Class, Function or Module instance
1.46 +unit refers to a micropython Class, Function or Module instance
2.1 --- a/micropython/common.py Mon Feb 27 23:22:33 2012 +0100
2.2 +++ b/micropython/common.py Wed Feb 29 00:39:20 2012 +0100
2.3 @@ -272,12 +272,16 @@
2.4 exc.unit_name = self.full_name()
2.5 raise
2.6
2.7 - def possible_accessor_types(self, node):
2.8 + def possible_accessor_types(self, node, defining_users=1):
2.9
2.10 """
2.11 Given annotations made during the inspection process, return all possible
2.12 type names and indications of static usage for a 'node' involved in
2.13 attribute access.
2.14 +
2.15 + If 'defining_users' is set to a false value, attempt to get the type
2.16 + names specifically applicable to the node, rather than retrieving more
2.17 + general definition-based type observations.
2.18 """
2.19
2.20 target_names = set()
2.21 @@ -291,8 +295,12 @@
2.22 # Since users such as branches may not provide type information,
2.23 # attempt to find defining users.
2.24
2.25 - for def_user in user._attrdefs or [user]:
2.26 - for target_name, is_static in def_user._attrtypes.get(node._username, []):
2.27 + if defining_users:
2.28 + for def_user in user._attrdefs or [user]:
2.29 + for target_name, is_static in def_user._attrtypes.get(node._username, []):
2.30 + target_names.add((target_name, is_static))
2.31 + else:
2.32 + for target_name, is_static in user._attrtypes.get(node._username, []):
2.33 target_names.add((target_name, is_static))
2.34
2.35 return target_names
3.1 --- a/micropython/data.py Mon Feb 27 23:22:33 2012 +0100
3.2 +++ b/micropython/data.py Wed Feb 29 00:39:20 2012 +0100
3.3 @@ -7,7 +7,7 @@
3.4 program but which are wrapped in context-dependent structures in the running
3.5 program.
3.6
3.7 -Copyright (C) 2007, 2008, 2009, 2010, 2011 Paul Boddie <paul@boddie.org.uk>
3.8 +Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 Paul Boddie <paul@boddie.org.uk>
3.9
3.10 This program is free software; you can redistribute it and/or modify it under
3.11 the terms of the GNU General Public License as published by the Free Software
3.12 @@ -418,10 +418,33 @@
3.13 # Visit each user and examine the attribute usage for each name.
3.14
3.15 for user in self.all_attribute_users:
3.16 - user._attrtypes = {}
3.17 - for name, usage in user._attrcombined.items():
3.18 - if usage is not None:
3.19 - user._attrtypes[name] = get_object_types_for_usage(usage, objtable, name, self.full_name())
3.20 + self._finalise_contributor(user, objtable)
3.21 +
3.22 + def _finalise_contributor(self, node, objtable):
3.23 +
3.24 + """
3.25 + Record the specific object types being used in various regions of a
3.26 + program unit.
3.27 + """
3.28 +
3.29 + if not hasattr(node, "_attrtypes"):
3.30 + node._attrtypes = self._deduce_types(node, objtable)
3.31 +
3.32 + for contributor in node._attrcontributors:
3.33 + self._finalise_contributor(contributor, objtable)
3.34 +
3.35 + def _deduce_types(self, user, objtable):
3.36 +
3.37 + """
3.38 + Deduce the types for names using attributes on the given 'user' node
3.39 + using the given 'objtable'.
3.40 + """
3.41 +
3.42 + attrtypes = {}
3.43 + for name, usage in user._attrcombined.items():
3.44 + if usage is not None:
3.45 + attrtypes[name] = get_object_types_for_usage(usage, objtable, name, self.full_name())
3.46 + return attrtypes
3.47
3.48 def get_usage_from_contributors(self, node):
3.49
3.50 @@ -588,11 +611,6 @@
3.51 if not hasattr(node, "_attrdefs"):
3.52 node._attrdefs = []
3.53
3.54 - # Eventual type information.
3.55 -
3.56 - if not hasattr(node, "_attrtypes"):
3.57 - node._attrtypes = {}
3.58 -
3.59 # Branch management methods.
3.60
3.61 def _new_branchpoint(self, loop_node=None):
4.1 --- a/micropython/inspect.py Mon Feb 27 23:22:33 2012 +0100
4.2 +++ b/micropython/inspect.py Wed Feb 29 00:39:20 2012 +0100
4.3 @@ -669,6 +669,7 @@
4.4 if expr.name == "self":
4.5 self.store_instance_attr(attrname)
4.6 self.use_attribute(expr.name, attrname, value) # NOTE: Impose constraints on the type given the hierarchy.
4.7 + self._visitAttrUser(expr, attrname, node, self.expr)
4.8
4.9 elif isinstance(value, Module):
4.10 self.store_module_attr(attrname, value)
5.1 --- a/micropython/report.py Mon Feb 27 23:22:33 2012 +0100
5.2 +++ b/micropython/report.py Wed Feb 29 00:39:20 2012 +0100
5.3 @@ -906,7 +906,7 @@
5.4
5.5 def visitAssAttr(self, node):
5.6 target_names = ["%s%s" % (is_static and "class " or "", target_name)
5.7 - for target_name, is_static in self.possible_accessor_types(node)]
5.8 + for target_name, is_static in self.possible_accessor_types(node, defining_users=0)]
5.9 self._span_start("assattr")
5.10 self._accessor_start(target_names)
5.11 self.dispatch(node.expr)
5.12 @@ -998,7 +998,7 @@
5.13
5.14 def visitGetattr(self, node):
5.15 target_names = ["%s%s" % (is_static and "class " or "", target_name)
5.16 - for target_name, is_static in self.possible_accessor_types(node)]
5.17 + for target_name, is_static in self.possible_accessor_types(node, defining_users=0)]
5.18 self._span_start("getattr")
5.19 self._accessor_start(target_names)
5.20 self.dispatch(node.expr)