aboutsummaryrefslogtreecommitdiffstats
path: root/liblangutil/Exceptions.h
blob: 5ad31ab207d6a8706ac9aa4df7832181d3844745 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
    This file is part of solidity.

    solidity is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    solidity is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with solidity.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * @author Christian <c@ethdev.com>
 * @date 2014
 * Solidity exception hierarchy.
 */

#pragma once

#include <string>
#include <utility>
#include <vector>
#include <memory>
#include <libdevcore/Exceptions.h>
#include <libdevcore/Assertions.h>
#include <liblangutil/SourceLocation.h>

namespace langutil
{
class Error;
using ErrorList = std::vector<std::shared_ptr<Error const>>;

struct CompilerError: virtual dev::Exception {};
struct InternalCompilerError: virtual dev::Exception {};
struct FatalError: virtual dev::Exception {};
struct UnimplementedFeatureError: virtual dev::Exception {};

/// Assertion that throws an InternalCompilerError containing the given description if it is not met.
#define solAssert(CONDITION, DESCRIPTION) \
        assertThrow(CONDITION, ::langutil::InternalCompilerError, DESCRIPTION)

#define solUnimplementedAssert(CONDITION, DESCRIPTION) \
        assertThrow(CONDITION, ::langutil::UnimplementedFeatureError, DESCRIPTION)

#define solUnimplemented(DESCRIPTION) \
        solUnimplementedAssert(false, DESCRIPTION)

class Error: virtual public dev::Exception
{
public:
    enum class Type
    {
        DeclarationError,
        DocstringParsingError,
        ParserError,
        TypeError,
        SyntaxError,
        Warning
    };

    explicit Error(
        Type _type,
        SourceLocation const& _location = SourceLocation(),
        std::string const& _description = std::string()
    );

    Error(Type _type, std::string const& _description, SourceLocation const& _location = SourceLocation());

    Type type() const { return m_type; }
    std::string const& typeName() const { return m_typeName; }

    /// helper functions
    static Error const* containsErrorOfType(ErrorList const& _list, Error::Type _type)
    {
        for (auto e: _list)
        {
            if (e->type() == _type)
                return e.get();
        }
        return nullptr;
    }
    static bool containsOnlyWarnings(ErrorList const& _list)
    {
        for (auto e: _list)
        {
            if (e->type() != Type::Warning)
                return false;
        }
        return true;
    }
private:
    Type m_type;
    std::string m_typeName;
};

using errorSourceLocationInfo = std::pair<std::string, SourceLocation>;

class SecondarySourceLocation
{
public:
    SecondarySourceLocation& append(std::string const& _errMsg, SourceLocation const& _sourceLocation)
    {
        infos.push_back(std::make_pair(_errMsg, _sourceLocation));
        return *this;
    }

    /// Limits the number of secondary source locations to 32 and appends a notice to the
    /// error message.
    void limitSize(std::string& _message)
    {
        size_t occurrences = infos.size();
        if (occurrences > 32)
        {
            infos.resize(32);
            _message += " Truncated from " + std::to_string(occurrences) + " to the first 32 occurrences.";
        }
    }

    std::vector<errorSourceLocationInfo> infos;
};

using errinfo_sourceLocation = boost::error_info<struct tag_sourceLocation, SourceLocation>;
using errinfo_secondarySourceLocation = boost::error_info<struct tag_secondarySourceLocation, SecondarySourceLocation>;


}