Lichen

Annotated results.py

343:e0879c83a439
2016-12-07 Paul Boddie Added support for reading to the end of a stream's input, fixing EOFError raising in fread by returning shorter amounts of data when EOF occurs, only raising an exception if no data was read before EOF occurred. Made the test input longer to exercise tests of reading remaining data.
paul@11 1
#!/usr/bin/env python
paul@11 2
paul@11 3
"""
paul@11 4
Result abstractions.
paul@11 5
paul@11 6
Copyright (C) 2016 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@226 33
    def reference(self):
paul@226 34
        return None
paul@226 35
paul@226 36
    def get_name(self):
paul@226 37
        return None
paul@226 38
paul@11 39
    def get_origin(self):
paul@11 40
        return None
paul@11 41
paul@226 42
    def static(self):
paul@118 43
        return None
paul@118 44
paul@226 45
    def final(self):
paul@226 46
        return None
paul@226 47
paul@226 48
    def has_kind(self, kinds):
paul@226 49
        return False
paul@226 50
paul@11 51
class AccessRef(Result):
paul@11 52
paul@11 53
    """
paul@11 54
    A reference to an attribute access that is generally only returned from a
paul@11 55
    processed access for possible initialiser resolution for assignments.
paul@11 56
    """
paul@11 57
paul@11 58
    def __init__(self, original_name, attrnames, number):
paul@11 59
        self.original_name = original_name
paul@11 60
        self.attrnames = attrnames
paul@11 61
        self.number = number
paul@11 62
paul@11 63
    def __repr__(self):
paul@11 64
        return "AccessRef(%r, %r, %r)" % (self.original_name, self.attrnames, self.number)
paul@11 65
paul@11 66
class InvocationRef(Result):
paul@11 67
paul@11 68
    "An invocation of a name reference."
paul@11 69
paul@11 70
    def __init__(self, name_ref):
paul@11 71
        self.name_ref = name_ref
paul@11 72
paul@27 73
    def reference(self):
paul@27 74
        origin = self.name_ref.get_origin()
paul@27 75
        if origin:
paul@27 76
            return Reference("<invoke>", origin)
paul@27 77
        else:
paul@27 78
            return Reference("<var>")
paul@27 79
paul@11 80
    def __repr__(self):
paul@11 81
        return "InvocationRef(%r)" % self.name_ref
paul@11 82
paul@11 83
class NameRef(Result):
paul@11 84
paul@11 85
    "A reference to a name."
paul@11 86
paul@11 87
    def __init__(self, name, expr=None):
paul@11 88
        self.name = name
paul@11 89
        self.expr = expr
paul@11 90
paul@11 91
    def is_name(self):
paul@11 92
        return True
paul@11 93
paul@11 94
    def final(self):
paul@11 95
        return None
paul@11 96
paul@11 97
    def __repr__(self):
paul@11 98
        return "NameRef(%r, %r)" % (self.name, self.expr)
paul@11 99
paul@11 100
class LocalNameRef(NameRef):
paul@11 101
paul@11 102
    "A reference to a local name."
paul@11 103
paul@11 104
    def __init__(self, name, number):
paul@11 105
        NameRef.__init__(self, name)
paul@11 106
        self.number = number
paul@11 107
paul@11 108
    def __repr__(self):
paul@11 109
        return "LocalNameRef(%r, %r)" % (self.name, self.number)
paul@11 110
paul@317 111
class ResolvedRef:
paul@11 112
paul@317 113
    "A resolved reference mix-in."
paul@11 114
paul@11 115
    def reference(self):
paul@11 116
        return self.ref
paul@11 117
paul@11 118
    def get_name(self):
paul@11 119
        return self.ref and self.ref.get_name() or None
paul@11 120
paul@11 121
    def get_origin(self):
paul@11 122
        return self.ref and self.ref.get_origin() or None
paul@11 123
paul@11 124
    def static(self):
paul@11 125
        return self.ref and self.ref.static() or None
paul@11 126
paul@11 127
    def final(self):
paul@11 128
        return self.ref and self.ref.final() or None
paul@11 129
paul@11 130
    def has_kind(self, kinds):
paul@11 131
        return self.ref and self.ref.has_kind(kinds)
paul@11 132
paul@338 133
    def is_constant_alias(self):
paul@338 134
        return self.ref and self.ref.is_constant_alias()
paul@338 135
paul@317 136
class ResolvedNameRef(ResolvedRef, NameRef):
paul@317 137
paul@317 138
    "A resolved name-based reference."
paul@317 139
paul@317 140
    def __init__(self, name, ref, expr=None):
paul@317 141
        NameRef.__init__(self, name, expr)
paul@317 142
        self.ref = ref
paul@317 143
paul@11 144
    def __repr__(self):
paul@11 145
        return "ResolvedNameRef(%r, %r, %r)" % (self.name, self.ref, self.expr)
paul@11 146
paul@11 147
class ConstantValueRef(ResolvedNameRef):
paul@11 148
paul@11 149
    "A constant reference representing a single literal value."
paul@11 150
paul@11 151
    def __init__(self, name, ref, value, number=None):
paul@11 152
        ResolvedNameRef.__init__(self, name, ref)
paul@11 153
        self.value = value
paul@11 154
        self.number = number
paul@11 155
paul@11 156
    def __repr__(self):
paul@11 157
        return "ConstantValueRef(%r, %r, %r, %r)" % (self.name, self.ref, self.value, self.number)
paul@11 158
paul@317 159
class InstanceRef(ResolvedRef, Result):
paul@11 160
paul@11 161
    "An instance reference."
paul@11 162
paul@11 163
    def __init__(self, ref):
paul@11 164
        self.ref = ref
paul@11 165
paul@11 166
    def reference(self):
paul@11 167
        return self.ref
paul@11 168
paul@11 169
    def __repr__(self):
paul@11 170
        return "InstanceRef(%r)" % self.ref
paul@11 171
paul@11 172
class LiteralSequenceRef(ResolvedNameRef):
paul@11 173
paul@11 174
    "A reference representing a sequence of values."
paul@11 175
paul@11 176
    def __init__(self, name, ref, node, items=None):
paul@11 177
        ResolvedNameRef.__init__(self, name, ref)
paul@11 178
        self.node = node
paul@11 179
        self.items = items
paul@11 180
paul@11 181
    def __repr__(self):
paul@11 182
        return "LiteralSequenceRef(%r, %r, %r, %r)" % (self.name, self.ref, self.node, self.items)
paul@11 183
paul@226 184
class VariableRef(Result):
paul@226 185
paul@226 186
    "A variable reference."
paul@226 187
paul@226 188
    def __repr__(self):
paul@226 189
        return "VariableRef()"
paul@226 190
paul@11 191
# vim: tabstop=4 expandtab shiftwidth=4