Lichen

results.py

821:ed27b57be1df
2018-01-15 Paul Boddie Introduced parameter-based attribute initialisation for broader testing.
     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