1 #!/usr/bin/env python 2 3 """ 4 Result abstractions. 5 6 Copyright (C) 2016, 2017 Paul Boddie <paul@boddie.org.uk> 7 8 This program is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free Software 10 Foundation; either version 3 of the License, or (at your option) any later 11 version. 12 13 This program is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 details. 17 18 You should have received a copy of the GNU General Public License along with 19 this program. If not, see <http://www.gnu.org/licenses/>. 20 """ 21 22 from referencing import Reference 23 24 # Classes representing inspection and translation observations. 25 26 class Result: 27 28 "An abstract expression result." 29 30 def is_name(self): 31 return False 32 33 def is_global_name(self): 34 return False 35 36 def reference(self): 37 return None 38 39 def references(self): 40 return None 41 42 def access_location(self): 43 return None 44 45 def access_locations(self): 46 return None 47 48 def context(self): 49 return None 50 51 def context_verified(self): 52 return None 53 54 def discards_temporary(self, test=True): 55 return None 56 57 def get_name(self): 58 return None 59 60 def get_origin(self): 61 return None 62 63 def static(self): 64 return None 65 66 def final(self): 67 return None 68 69 def has_kind(self, kinds): 70 return False 71 72 class AccessRef(Result): 73 74 """ 75 A reference to an attribute access that is generally only returned from a 76 processed access for possible initialiser resolution for assignments. 77 """ 78 79 def __init__(self, original_name, attrnames, number): 80 self.original_name = original_name 81 self.attrnames = attrnames 82 self.number = number 83 84 def __repr__(self): 85 return "AccessRef(%r, %r, %r)" % (self.original_name, self.attrnames, self.number) 86 87 class InvocationRef(Result): 88 89 "An invocation of a name reference." 90 91 def __init__(self, name_ref): 92 self.name_ref = name_ref 93 94 def reference(self): 95 origin = self.name_ref.get_origin() 96 if origin: 97 return Reference("<invoke>", origin) 98 else: 99 return Reference("<var>") 100 101 def __repr__(self): 102 return "InvocationRef(%r)" % self.name_ref 103 104 class NameRef(Result): 105 106 "A reference to a name." 107 108 def __init__(self, name, expr=None, is_global=False): 109 self.name = name 110 self.expr = expr 111 self.is_global = is_global 112 113 def is_name(self): 114 return True 115 116 def is_global_name(self): 117 return self.is_global 118 119 def final(self): 120 return None 121 122 def __repr__(self): 123 return "NameRef(%r, %r, %r)" % (self.name, self.expr, self.is_global) 124 125 class LocalNameRef(NameRef): 126 127 "A reference to a local name." 128 129 def __init__(self, name, number): 130 NameRef.__init__(self, name, is_global=False) 131 self.number = number 132 133 def __repr__(self): 134 return "LocalNameRef(%r, %r)" % (self.name, self.number) 135 136 class ResolvedRef: 137 138 "A resolved reference mix-in." 139 140 def __init__(self, ref): 141 self.ref = ref 142 143 def reference(self): 144 return self.ref 145 146 def references(self): 147 return [self.ref] 148 149 def get_name(self): 150 return self.ref and self.ref.get_name() or None 151 152 def get_origin(self): 153 return self.ref and self.ref.get_origin() or None 154 155 def static(self): 156 return self.ref and self.ref.static() or None 157 158 def final(self): 159 return self.ref and self.ref.final() or None 160 161 def has_kind(self, kinds): 162 return self.ref and self.ref.has_kind(kinds) 163 164 def is_constant_alias(self): 165 return self.ref and self.ref.is_constant_alias() 166 167 class ResolvedNameRef(ResolvedRef, NameRef): 168 169 "A resolved name-based reference." 170 171 def __init__(self, name, ref, expr=None, is_global=False): 172 NameRef.__init__(self, name, expr, is_global) 173 ResolvedRef.__init__(self, ref) 174 175 def __repr__(self): 176 return "ResolvedNameRef(%r, %r, %r, %r)" % (self.name, self.ref, self.expr, self.is_global) 177 178 class ConstantValueRef(ResolvedNameRef): 179 180 "A constant reference representing a single literal value." 181 182 def __init__(self, name, ref, value, number=None): 183 ResolvedNameRef.__init__(self, name, ref) 184 self.value = value 185 self.number = number 186 187 def __repr__(self): 188 return "ConstantValueRef(%r, %r, %r, %r)" % (self.name, self.ref, self.value, self.number) 189 190 class InstanceRef(ResolvedRef, Result): 191 192 "An instance reference." 193 194 def reference(self): 195 return self.ref 196 197 def __repr__(self): 198 return "InstanceRef(%r)" % self.ref 199 200 class LiteralSequenceRef(ResolvedNameRef): 201 202 "A reference representing a sequence of values." 203 204 def __init__(self, name, ref, node, items=None): 205 ResolvedNameRef.__init__(self, name, ref) 206 self.node = node 207 self.items = items 208 209 def __repr__(self): 210 return "LiteralSequenceRef(%r, %r, %r, %r)" % (self.name, self.ref, self.node, self.items) 211 212 class MultipleRef(Result): 213 214 "A multiple outcome result." 215 216 def __init__(self, results): 217 self.results = results 218 219 def reference(self): 220 refs = set(self.references()) 221 ref = len(refs) == 1 and list(refs)[0] or Reference("<var>") 222 223 def references(self): 224 refs = [] 225 for result in self.results: 226 refs.append(result.reference()) 227 return refs 228 229 def __repr__(self): 230 return "MultipleRef(%r)" % self.results 231 232 class VariableRef(Result): 233 234 "A variable reference." 235 236 def __repr__(self): 237 return "VariableRef()" 238 239 # vim: tabstop=4 expandtab shiftwidth=4