1.1 --- a/deducer.py Fri Nov 25 18:36:10 2016 +0100
1.2 +++ b/deducer.py Fri Nov 25 18:36:45 2016 +0100
1.3 @@ -25,7 +25,7 @@
1.4 sorted_output, CommonOutput
1.5 from encoders import encode_attrnames, encode_access_location, \
1.6 encode_constrained, encode_location, encode_usage, \
1.7 - get_kinds, test_for_kinds, test_for_type
1.8 + get_kinds, test_label_for_kind, test_label_for_type
1.9 from errors import DeduceError
1.10 from os.path import join
1.11 from referencing import combine_types, is_single_class_type, separate_types, \
1.12 @@ -260,23 +260,25 @@
1.13 print >>f_warnings, encode_location(location), "; ".join(map(encode_usage, attrnames))
1.14
1.15 guard_test = self.accessor_guard_tests.get(location)
1.16 + if guard_test:
1.17 + guard_test_type, guard_test_arg = guard_test
1.18
1.19 # Write specific type guard details.
1.20
1.21 - if guard_test and guard_test.startswith("specific"):
1.22 - print >>f_guards, encode_location(location), guard_test, \
1.23 - get_kinds(all_types)[0], \
1.24 + if guard_test and guard_test_type == "specific":
1.25 + print >>f_guards, encode_location(location), "-".join(guard_test), \
1.26 + first(get_kinds(all_types)), \
1.27 sorted_output(all_types)
1.28
1.29 # Write common type guard details.
1.30
1.31 - elif guard_test and guard_test.startswith("common"):
1.32 - print >>f_guards, encode_location(location), guard_test, \
1.33 - get_kinds(all_general_types)[0], \
1.34 + elif guard_test and guard_test_type == "common":
1.35 + print >>f_guards, encode_location(location), "-".join(guard_test), \
1.36 + first(get_kinds(all_general_types)), \
1.37 sorted_output(all_general_types)
1.38
1.39 print >>f_type_summary, encode_location(location), encode_constrained(constrained), \
1.40 - guard_test or "unguarded", sorted_output(all_general_types), len(all_types)
1.41 + guard_test and "-".join(guard_test) or "unguarded", sorted_output(all_general_types), len(all_types)
1.42
1.43 finally:
1.44 f_type_summary.close()
1.45 @@ -362,18 +364,18 @@
1.46
1.47 # Write the need to test at run time.
1.48
1.49 - if test_type == "validate":
1.50 - print >>f_tests, encode_access_location(location), test_type
1.51 + if test_type[0] == "validate":
1.52 + print >>f_tests, encode_access_location(location), "-".join(test_type)
1.53
1.54 # Write any type checks for anonymous accesses.
1.55
1.56 elif test_type and self.reference_test_accessor_type.get(location):
1.57 - print >>f_tests, encode_access_location(location), test_type, \
1.58 + print >>f_tests, encode_access_location(location), "-".join(test_type[1:]), \
1.59 sorted_output(all_accessed_attrs), \
1.60 self.reference_test_accessor_type[location]
1.61
1.62 print >>f_attr_summary, encode_access_location(location), encode_constrained(constrained), \
1.63 - test_type or "untested", sorted_output(all_accessed_attrs)
1.64 + test_type and "-".join(test_type) or "untested", sorted_output(all_accessed_attrs)
1.65
1.66 else:
1.67 print >>f_warnings, encode_access_location(location)
1.68 @@ -409,7 +411,8 @@
1.69
1.70 print >>f_attrs, encode_access_location(location), \
1.71 name or "{}", \
1.72 - test, test_type or "{}", \
1.73 + test and "-".join(test) or "{}", \
1.74 + test_type or "{}", \
1.75 base or "{}", \
1.76 ".".join(traversed) or "{}", \
1.77 ".".join(traversal_modes) or "{}", \
1.78 @@ -473,16 +476,16 @@
1.79 # Record specific type guard details.
1.80
1.81 if len(all_types) == 1:
1.82 - self.accessor_guard_tests[location] = test_for_type("specific", first(all_types))
1.83 + self.accessor_guard_tests[location] = ("specific", test_label_for_type(first(all_types)))
1.84 elif is_single_class_type(all_types):
1.85 - self.accessor_guard_tests[location] = "specific-object"
1.86 + self.accessor_guard_tests[location] = ("specific", "object")
1.87
1.88 # Record common type guard details.
1.89
1.90 elif len(all_general_types) == 1:
1.91 - self.accessor_guard_tests[location] = test_for_type("common", first(all_types))
1.92 + self.accessor_guard_tests[location] = ("common", test_label_for_type(first(all_types)))
1.93 elif is_single_class_type(all_general_types):
1.94 - self.accessor_guard_tests[location] = "common-object"
1.95 + self.accessor_guard_tests[location] = ("common", "object")
1.96
1.97 # Otherwise, no convenient guard can be defined.
1.98
1.99 @@ -581,15 +584,15 @@
1.100
1.101 if constrained:
1.102 if single_accessor_type:
1.103 - self.reference_test_types[location] = test_for_type("constrained-specific", first(all_accessor_types))
1.104 + self.reference_test_types[location] = ("constrained", "specific", test_label_for_type(first(all_accessor_types)))
1.105 elif single_accessor_class_type:
1.106 - self.reference_test_types[location] = "constrained-specific-object"
1.107 + self.reference_test_types[location] = ("constrained", "specific", "object")
1.108 elif single_accessor_general_type:
1.109 - self.reference_test_types[location] = test_for_type("constrained-common", first(all_accessor_general_types))
1.110 + self.reference_test_types[location] = ("constrained", "common", test_label_for_type(first(all_accessor_general_types)))
1.111 elif single_accessor_general_class_type:
1.112 - self.reference_test_types[location] = "constrained-common-object"
1.113 + self.reference_test_types[location] = ("constrained", "common", "object")
1.114 else:
1.115 - self.reference_test_types[location] = "constrained-many"
1.116 + self.reference_test_types[location] = ("constrained", "many")
1.117
1.118 # Suitably guarded accesses, where the nature of the
1.119 # accessor can be guaranteed, do not require the attribute
1.120 @@ -598,13 +601,13 @@
1.121
1.122 elif guarded and all_accessed_attrs.issubset(guard_attrs):
1.123 if single_accessor_type:
1.124 - self.reference_test_types[location] = test_for_type("guarded-specific", first(all_accessor_types))
1.125 + self.reference_test_types[location] = ("guarded", "specific", test_label_for_type(first(all_accessor_types)))
1.126 elif single_accessor_class_type:
1.127 - self.reference_test_types[location] = "guarded-specific-object"
1.128 + self.reference_test_types[location] = ("guarded", "specific", "object")
1.129 elif single_accessor_general_type:
1.130 - self.reference_test_types[location] = test_for_type("guarded-common", first(all_accessor_general_types))
1.131 + self.reference_test_types[location] = ("guarded", "common", test_label_for_type(first(all_accessor_general_types)))
1.132 elif single_accessor_general_class_type:
1.133 - self.reference_test_types[location] = "guarded-common-object"
1.134 + self.reference_test_types[location] = ("guarded", "common", "object")
1.135
1.136 # Record the need to test the type of anonymous and
1.137 # unconstrained accessors.
1.138 @@ -614,9 +617,9 @@
1.139 if provider != '__builtins__.object':
1.140 all_accessor_kinds = set(get_kinds(all_accessor_types))
1.141 if len(all_accessor_kinds) == 1:
1.142 - test_type = test_for_kinds("specific", all_accessor_kinds)
1.143 + test_type = ("test", "specific", first(all_accessor_kinds))
1.144 else:
1.145 - test_type = "specific-object"
1.146 + test_type = ("test", "specific", "object")
1.147 self.reference_test_types[location] = test_type
1.148 self.reference_test_accessor_type[location] = provider
1.149
1.150 @@ -625,16 +628,16 @@
1.151 if provider != '__builtins__.object':
1.152 all_accessor_kinds = set(get_kinds(all_accessor_general_types))
1.153 if len(all_accessor_kinds) == 1:
1.154 - test_type = test_for_kinds("common", all_accessor_kinds)
1.155 + test_type = ("test", "common", first(all_accessor_kinds))
1.156 else:
1.157 - test_type = "common-object"
1.158 + test_type = ("test", "common", "object")
1.159 self.reference_test_types[location] = test_type
1.160 self.reference_test_accessor_type[location] = provider
1.161
1.162 # Record the need to test the identity of the attribute.
1.163
1.164 else:
1.165 - self.reference_test_types[location] = "validate"
1.166 + self.reference_test_types[location] = ("validate",)
1.167
1.168 def initialise_access_plans(self):
1.169
1.170 @@ -1749,54 +1752,11 @@
1.171
1.172 return attrs
1.173
1.174 - constrained_specific_tests = (
1.175 - "constrained-specific-instance",
1.176 - "constrained-specific-type",
1.177 - "constrained-specific-object",
1.178 - )
1.179 -
1.180 - constrained_common_tests = (
1.181 - "constrained-common-instance",
1.182 - "constrained-common-type",
1.183 - "constrained-common-object",
1.184 - )
1.185 -
1.186 - guarded_specific_tests = (
1.187 - "guarded-specific-instance",
1.188 - "guarded-specific-type",
1.189 - "guarded-specific-object",
1.190 - )
1.191 -
1.192 - guarded_common_tests = (
1.193 - "guarded-common-instance",
1.194 - "guarded-common-type",
1.195 - "guarded-common-object",
1.196 - )
1.197 -
1.198 - specific_tests = (
1.199 - "specific-instance",
1.200 - "specific-type",
1.201 - "specific-object",
1.202 - )
1.203 -
1.204 - common_tests = (
1.205 - "common-instance",
1.206 - "common-type",
1.207 - "common-object",
1.208 - )
1.209 -
1.210 class_tests = (
1.211 - "guarded-specific-type",
1.212 - "guarded-common-type",
1.213 - "specific-type",
1.214 - "common-type",
1.215 - )
1.216 -
1.217 - class_or_instance_tests = (
1.218 - "guarded-specific-object",
1.219 - "guarded-common-object",
1.220 - "specific-object",
1.221 - "common-object",
1.222 + ("guarded", "specific", "type"),
1.223 + ("guarded", "common", "type"),
1.224 + ("test", "specific", "type"),
1.225 + ("test", "common", "type"),
1.226 )
1.227
1.228 def get_access_plan(self, location):
1.229 @@ -1883,22 +1843,22 @@
1.230
1.231 # Usage of previously-generated guard and test details.
1.232
1.233 - elif test in self.constrained_specific_tests:
1.234 + elif test[:2] == ("constrained", "specific"):
1.235 ref = first(accessor_types)
1.236
1.237 - elif test in self.constrained_common_tests:
1.238 + elif test[:2] == ("constrained", "common"):
1.239 ref = first(accessor_general_types)
1.240
1.241 - elif test in self.guarded_specific_tests:
1.242 + elif test[:2] == ("guarded", "specific"):
1.243 ref = first(accessor_types)
1.244
1.245 - elif test in self.guarded_common_tests:
1.246 + elif test[:2] == ("guarded", "common"):
1.247 ref = first(accessor_general_types)
1.248
1.249 # For attribute-based tests, tentatively identify a dynamic base.
1.250 # Such tests allow single or multiple kinds of a type.
1.251
1.252 - elif test in self.common_tests or test in self.specific_tests:
1.253 + elif test[0] == "test" and test[1] in ("common", "specific"):
1.254 dynamic_base = test_type
1.255
1.256 # Static accessors.