Lichen

Annotated errors.py

90:c7ddfc4525da
2016-10-08 Paul Boddie Added some support for eliminating accessor class types where the provided attributes are invoked and are unbound methods. This uses a more sophisticated method involving usage observations that incorporate invocation information, permitting classes as accessors if paths through the code support them, even if other paths require instances as accessors to invoke methods.
paul@0 1
#!/usr/bin/env python
paul@0 2
paul@0 3
"""
paul@0 4
Error classes.
paul@0 5
paul@0 6
Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012
paul@0 7
              2014, 2016 Paul Boddie <paul@boddie.org.uk>
paul@0 8
paul@0 9
This program is free software; you can redistribute it and/or modify it under
paul@0 10
the terms of the GNU General Public License as published by the Free Software
paul@0 11
Foundation; either version 3 of the License, or (at your option) any later
paul@0 12
version.
paul@0 13
paul@0 14
This program is distributed in the hope that it will be useful, but WITHOUT
paul@0 15
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
paul@0 16
FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
paul@0 17
details.
paul@0 18
paul@0 19
You should have received a copy of the GNU General Public License along with
paul@0 20
this program.  If not, see <http://www.gnu.org/licenses/>.
paul@0 21
"""
paul@0 22
paul@0 23
class ProcessingError(Exception):
paul@0 24
paul@0 25
    "A processing error."
paul@0 26
paul@0 27
    pass
paul@0 28
paul@0 29
class ProgramError(ProcessingError):
paul@0 30
paul@0 31
    "A general program processing error."
paul@0 32
paul@0 33
    def __init__(self, message):
paul@0 34
        self.message = message
paul@0 35
paul@0 36
    def __repr__(self):
paul@0 37
        return "%s(%r)" % (self.__class__.__name__, self.message)
paul@0 38
paul@0 39
    def __str__(self):
paul@0 40
        return self.message
paul@0 41
paul@0 42
class NodeProcessingError(ProcessingError):
paul@0 43
paul@0 44
    "A processing error associated with a particular program node."
paul@0 45
paul@0 46
    def __init__(self, message, unit_name=None, astnode=None):
paul@0 47
        self.message = message
paul@0 48
        self.unit_name = unit_name
paul@0 49
        self.astnode = astnode
paul@0 50
paul@0 51
    def get_lineno(self, node):
paul@0 52
paul@0 53
        "Search for line number information associated with 'node'."
paul@0 54
paul@0 55
        if node is None:
paul@0 56
            return None
paul@0 57
paul@0 58
        lineno = node.lineno
paul@0 59
        if lineno is not None:
paul@0 60
            return lineno
paul@0 61
        else:
paul@0 62
            for child in node.getChildNodes():
paul@0 63
                lineno = self.get_lineno(child)
paul@0 64
                if lineno is not None:
paul@0 65
                    return lineno
paul@0 66
        return None
paul@0 67
paul@0 68
    def __repr__(self):
paul@0 69
        return "%s(%r, %r, %r)" % (self.__class__.__name__, self.message, self.unit_name, self.astnode)
paul@0 70
paul@0 71
    def __str__(self):
paul@0 72
        lineno = self.get_lineno(self.astnode)
paul@0 73
        return "Error in %s%s: %s" % (self.unit_name, lineno and (" at line %s" % lineno) or "", self.message)
paul@0 74
paul@0 75
class InspectError(NodeProcessingError):
paul@0 76
paul@0 77
    "An error during the module inspection process."
paul@0 78
paul@0 79
    pass
paul@0 80
paul@87 81
class DeduceError(ProgramError):
paul@71 82
paul@71 83
    "An error during the deduction process."
paul@71 84
paul@87 85
    def __str__(self):
paul@87 86
        return "Error in deduction: %s" % self.message
paul@71 87
paul@0 88
class TranslateError(NodeProcessingError):
paul@0 89
paul@0 90
    "An error during the module translation process."
paul@0 91
paul@0 92
    pass
paul@0 93
paul@0 94
# vim: tabstop=4 expandtab shiftwidth=4