1.1 --- a/deducer.py Fri Oct 07 21:36:08 2016 +0200
1.2 +++ b/deducer.py Sat Oct 08 00:33:32 2016 +0200
1.3 @@ -20,7 +20,7 @@
1.4 """
1.5
1.6 from common import first, get_attrname_from_location, get_attrnames, \
1.7 - get_name_path, init_item, make_key, sorted_output, \
1.8 + get_name_path, init_item, sorted_output, \
1.9 CommonOutput
1.10 from encoders import encode_attrnames, encode_access_location, \
1.11 encode_constrained, encode_location, encode_usage, \
1.12 @@ -699,7 +699,7 @@
1.13 for attrnames in all_attrnames:
1.14 attrname = get_attrnames(attrnames)[-1]
1.15 access_location = (location, None, attrnames, 0)
1.16 - self.add_usage_term(access_location, [attrname])
1.17 + self.add_usage_term(access_location, ((attrname, False),))
1.18
1.19 def add_usage(self, assignments, path):
1.20
1.21 @@ -713,21 +713,19 @@
1.22 for i, usages in enumerate(versions):
1.23 location = (path, name, None, i)
1.24
1.25 - for attrnames in usages:
1.26 - self.add_usage_term(location, attrnames)
1.27 -
1.28 - def add_usage_term(self, location, attrnames):
1.29 + for usage in usages:
1.30 + self.add_usage_term(location, usage)
1.31 +
1.32 + def add_usage_term(self, location, usage):
1.33
1.34 """
1.35 - For 'location' and using 'attrnames' as a description of usage, record
1.36 + For 'location' and using 'usage' as a description of usage, record
1.37 in the usage index a mapping from the usage to 'location', and record in
1.38 the location index a mapping from 'location' to the usage.
1.39 """
1.40
1.41 - key = make_key(attrnames)
1.42 -
1.43 init_item(self.location_index, location, set)
1.44 - self.location_index[location].add(key)
1.45 + self.location_index[location].add(usage)
1.46
1.47 def init_accessors(self):
1.48
1.49 @@ -803,11 +801,9 @@
1.50
1.51 for location in accessor_locations:
1.52 for usage in self.location_index[location]:
1.53 - key = make_key(usage)
1.54 -
1.55 if assignment:
1.56 - init_item(self.assigned_attrs, key, set)
1.57 - self.assigned_attrs[key].add((path, name, attrnames))
1.58 + init_item(self.assigned_attrs, usage, set)
1.59 + self.assigned_attrs[usage].add((path, name, attrnames))
1.60
1.61 def init_aliases(self):
1.62
1.63 @@ -1010,31 +1006,31 @@
1.64 init_item(attr_types, attrname, set)
1.65 attr_types[attrname].add(name)
1.66
1.67 - def get_class_types_for_usage(self, attrnames):
1.68 -
1.69 - "Return names of classes supporting the given 'attrnames'."
1.70 -
1.71 - return self._get_types_for_usage(attrnames, self.attr_class_types, self.importer.all_class_attrs)
1.72 -
1.73 - def get_instance_types_for_usage(self, attrnames):
1.74 + def get_class_types_for_usage(self, usage):
1.75 +
1.76 + "Return names of classes supporting the given 'usage'."
1.77 +
1.78 + return self._get_types_for_usage(usage, self.attr_class_types, self.importer.all_class_attrs)
1.79 +
1.80 + def get_instance_types_for_usage(self, usage):
1.81
1.82 """
1.83 - Return names of classes whose instances support the given 'attrnames'
1.84 + Return names of classes whose instances support the given 'usage'
1.85 (as either class or instance attributes).
1.86 """
1.87
1.88 - return self._get_types_for_usage(attrnames, self.attr_instance_types, self.importer.all_combined_attrs)
1.89 -
1.90 - def get_module_types_for_usage(self, attrnames):
1.91 -
1.92 - "Return names of modules supporting the given 'attrnames'."
1.93 -
1.94 - return self._get_types_for_usage(attrnames, self.attr_module_types, self.importer.all_module_attrs)
1.95 -
1.96 - def _get_types_for_usage(self, attrnames, attr_types, attrs):
1.97 + return self._get_types_for_usage(usage, self.attr_instance_types, self.importer.all_combined_attrs)
1.98 +
1.99 + def get_module_types_for_usage(self, usage):
1.100 +
1.101 + "Return names of modules supporting the given 'usage'."
1.102 +
1.103 + return self._get_types_for_usage(usage, self.attr_module_types, self.importer.all_module_attrs)
1.104 +
1.105 + def _get_types_for_usage(self, usage, attr_types, attrs):
1.106
1.107 """
1.108 - For the given 'attrnames' representing attribute usage, return types
1.109 + For the given 'usage' representing attribute usage, return types
1.110 recorded in the 'attr_types' attribute-to-types mapping that support
1.111 such usage, with the given 'attrs' type-to-attributes mapping used to
1.112 quickly assess whether a type supports all of the stated attributes.
1.113 @@ -1042,9 +1038,13 @@
1.114
1.115 # Where no attributes are used, any type would be acceptable.
1.116
1.117 - if not attrnames:
1.118 + if not usage:
1.119 return attrs.keys()
1.120
1.121 + attrnames = []
1.122 + for attrname, invocation in usage:
1.123 + attrnames.append(attrname)
1.124 +
1.125 types = []
1.126
1.127 # Obtain types supporting the first attribute name...
1.128 @@ -1389,7 +1389,7 @@
1.129
1.130 else:
1.131 self.init_definition_details(location)
1.132 - self.record_types_for_usage(location, [attrname])
1.133 + self.record_types_for_usage(location, [(attrname, False)])
1.134
1.135 constrained = location in self.accessor_constrained and constrained
1.136
1.137 @@ -1418,7 +1418,7 @@
1.138 'attrname' for type deduction.
1.139 """
1.140
1.141 - usage = [attrname]
1.142 + usage = ((attrname, False),)
1.143
1.144 class_types = self.get_class_types_for_usage(usage)
1.145 only_instance_types = set(self.get_instance_types_for_usage(usage)).difference(class_types)