Lichen

Annotated results.py

1027:dd0745ab8b8a
5 months ago Paul Boddie Reordered GCC arguments to prevent linking failures. Someone decided to change the GCC invocation or linking semantics at some point, meaning that libraries specified "too early" in the argument list no longer provide the symbols required by the program objects, whereas specifying them at the end of the argument list allows those symbols to be found and obtained.
paul@11 1
#!/usr/bin/env python
paul@11 2
paul@11 3
"""
paul@11 4
Result abstractions.
paul@11 5
paul@510 6
Copyright (C) 2016, 2017 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@317 167
class ResolvedNameRef(ResolvedRef, NameRef):
paul@317 168
paul@317 169
    "A resolved name-based reference."
paul@317 170
paul@603 171
    def __init__(self, name, ref, expr=None, is_global=False):
paul@603 172
        NameRef.__init__(self, name, expr, is_global)
paul@552 173
        ResolvedRef.__init__(self, ref)
paul@317 174
paul@11 175
    def __repr__(self):
paul@603 176
        return "ResolvedNameRef(%r, %r, %r, %r)" % (self.name, self.ref, self.expr, self.is_global)
paul@11 177
paul@11 178
class ConstantValueRef(ResolvedNameRef):
paul@11 179
paul@11 180
    "A constant reference representing a single literal value."
paul@11 181
paul@11 182
    def __init__(self, name, ref, value, number=None):
paul@11 183
        ResolvedNameRef.__init__(self, name, ref)
paul@11 184
        self.value = value
paul@11 185
        self.number = number
paul@11 186
paul@11 187
    def __repr__(self):
paul@11 188
        return "ConstantValueRef(%r, %r, %r, %r)" % (self.name, self.ref, self.value, self.number)
paul@11 189
paul@317 190
class InstanceRef(ResolvedRef, Result):
paul@11 191
paul@11 192
    "An instance reference."
paul@11 193
paul@11 194
    def reference(self):
paul@11 195
        return self.ref
paul@11 196
paul@11 197
    def __repr__(self):
paul@11 198
        return "InstanceRef(%r)" % self.ref
paul@11 199
paul@11 200
class LiteralSequenceRef(ResolvedNameRef):
paul@11 201
paul@11 202
    "A reference representing a sequence of values."
paul@11 203
paul@11 204
    def __init__(self, name, ref, node, items=None):
paul@11 205
        ResolvedNameRef.__init__(self, name, ref)
paul@11 206
        self.node = node
paul@11 207
        self.items = items
paul@11 208
paul@11 209
    def __repr__(self):
paul@11 210
        return "LiteralSequenceRef(%r, %r, %r, %r)" % (self.name, self.ref, self.node, self.items)
paul@11 211
paul@794 212
class MultipleRef(Result):
paul@794 213
paul@794 214
    "A multiple outcome result."
paul@794 215
paul@794 216
    def __init__(self, results):
paul@794 217
        self.results = results
paul@794 218
paul@794 219
    def reference(self):
paul@794 220
        refs = set(self.references())
paul@794 221
        ref = len(refs) == 1 and list(refs)[0] or Reference("<var>")
paul@794 222
paul@794 223
    def references(self):
paul@794 224
        refs = []
paul@794 225
        for result in self.results:
paul@794 226
            refs.append(result.reference())
paul@794 227
        return refs
paul@794 228
paul@794 229
    def __repr__(self):
paul@794 230
        return "MultipleRef(%r)" % self.results
paul@794 231
paul@226 232
class VariableRef(Result):
paul@226 233
paul@226 234
    "A variable reference."
paul@226 235
paul@226 236
    def __repr__(self):
paul@226 237
        return "VariableRef()"
paul@226 238
paul@11 239
# vim: tabstop=4 expandtab shiftwidth=4