Lichen

Annotated errors.py

118:900d641f42d6
2016-10-20 Paul Boddie Added some more support for generating invocation code, distinguishing between static invocation targets that are identified and whose functions can be obtained directly and other kinds of targets whose functions must be obtained via the special attribute.
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