Lichen

Annotated results.py

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