• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ArkScript-lang / Ark / 11445793250

21 Oct 2024 05:51PM UTC coverage: 76.877% (+0.4%) from 76.499%
11445793250

push

github

SuperFola
refactor(macro): removing useless constructor

5130 of 6673 relevant lines covered (76.88%)

9379.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

52.71
/src/arkreactor/Exceptions.cpp
1
#include <Ark/Exceptions.hpp>
2

3
#include <sstream>
4
#include <algorithm>
5
#include <fmt/core.h>
6
#include <fmt/color.h>
7
#include <fmt/ostream.h>
8

9
#include <Ark/Constants.hpp>
10
#include <Ark/Utils.hpp>
11
#include <Ark/Files.hpp>
12
#include <Ark/Literals.hpp>
13
#include <Ark/Compiler/AST/Node.hpp>
14

15
namespace Ark::Diagnostics
16
{
17
    struct LineColorContextCounts
68✔
18
    {
19
        int open_parentheses = 0;
68✔
20
        int open_square_braces = 0;
68✔
21
        int open_curly_braces = 0;
68✔
22
    };
23

24
    inline bool isPairableChar(const char c)
×
25
    {
×
26
        return c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}';
×
27
    }
28

29
    void colorizeLine(const std::string& line, LineColorContextCounts& line_color_context_counts, std::ostream& ss)
×
30
    {
×
31
        // clang-format off
32
        constexpr std::array pairing_color {
×
33
            fmt::color::light_blue,
34
            fmt::color::light_green,
35
            fmt::color::light_salmon,
36
            fmt::color::light_yellow,
37
            fmt::color::light_cyan,
38
            fmt::color::light_coral
39
        };
40
        // clang-format on
41
        constexpr std::size_t pairing_color_size = pairing_color.size();
×
42

43
        for (const char& c : line)
×
44
        {
45
            if (isPairableChar(c))
×
46
            {
47
                std::size_t pairing_color_index = 0;
×
48

49
                switch (c)
×
50
                {
×
51
                    case '(':
52
                        pairing_color_index = static_cast<std::size_t>(std::abs(line_color_context_counts.open_parentheses)) % pairing_color_size;
×
53
                        line_color_context_counts.open_parentheses++;
×
54
                        break;
×
55
                    case ')':
56
                        line_color_context_counts.open_parentheses--;
×
57
                        pairing_color_index = static_cast<std::size_t>(std::abs(line_color_context_counts.open_parentheses)) % pairing_color_size;
×
58
                        break;
×
59
                    case '[':
60
                        pairing_color_index = static_cast<std::size_t>(std::abs(line_color_context_counts.open_square_braces)) % pairing_color_size;
×
61
                        line_color_context_counts.open_square_braces++;
×
62
                        break;
×
63
                    case ']':
64
                        line_color_context_counts.open_square_braces--;
×
65
                        pairing_color_index = static_cast<std::size_t>(std::abs(line_color_context_counts.open_square_braces)) % pairing_color_size;
×
66
                        break;
×
67
                    case '{':
68
                        pairing_color_index = static_cast<std::size_t>(std::abs(line_color_context_counts.open_curly_braces)) % pairing_color_size;
×
69
                        line_color_context_counts.open_curly_braces++;
×
70
                        break;
×
71
                    case '}':
72
                        line_color_context_counts.open_curly_braces--;
×
73
                        pairing_color_index = static_cast<std::size_t>(std::abs(line_color_context_counts.open_curly_braces)) % pairing_color_size;
×
74
                        break;
×
75
                    default:
76
                        break;
×
77
                }
×
78

79
                fmt::print(ss, "{}", fmt::styled(c, fmt::fg(pairing_color[pairing_color_index])));
×
80
            }
×
81
            else
82
                fmt::print(ss, "{}", c);
×
83
        }
×
84
    }
×
85

86
    void makeContext(std::ostream& os, const std::string& code, const std::size_t target_line, const std::size_t col_start, const std::size_t sym_size, const bool colorize)
68✔
87
    {
68✔
88
        using namespace Ark::literals;
89

90
        const std::vector<std::string> ctx = Utils::splitString(code, '\n');
68✔
91
        if (target_line >= ctx.size())
68✔
92
            return;
×
93

94
        const std::size_t first_line = target_line >= 3 ? target_line - 3 : 0;
68✔
95
        const std::size_t last_line = (target_line + 3) <= ctx.size() ? target_line + 3 : ctx.size();
68✔
96
        std::size_t overflow = (col_start + sym_size < ctx[target_line].size()) ? 0 : col_start + sym_size - ctx[target_line].size();  // number of characters that are on more lines below
68✔
97
        LineColorContextCounts line_color_context_counts;
68✔
98

99
        for (auto i = first_line; i < last_line; ++i)
237✔
100
        {
101
            fmt::print(os, "{: >5} |{}", i + 1, !ctx[i].empty() ? " " : "");
169✔
102
            if (colorize)
169✔
103
                colorizeLine(ctx[i], line_color_context_counts, os);
×
104
            else
105
                fmt::print(os, "{}", ctx[i]);
169✔
106
            fmt::print(os, "\n");
169✔
107

108
            if (i == target_line || (i > target_line && overflow > 0))
169✔
109
            {
110
                fmt::print(os, "      |");
76✔
111
                // if we have an overflow then we start at the beginning of the line
112
                const std::size_t curr_col_start = (overflow == 0) ? col_start : 0;
76✔
113
                // if we have an overflow, it is used as the end of the line
114
                const std::size_t col_end = (i == target_line) ? std::min<std::size_t>(col_start + sym_size, ctx[target_line].size())
84✔
115
                                                               : std::min<std::size_t>(overflow, ctx[i].size());
8✔
116
                // update the overflow to avoid going here again if not needed
117
                overflow = (overflow > ctx[i].size()) ? overflow - ctx[i].size() : 0;
76✔
118

119
                fmt::print(
228✔
120
                    os,
76✔
121
                    "{: <{}}{:~<{}}\n",
76✔
122
                    // padding of spaces
123
                    " ",
124
                    std::max(1_z, curr_col_start),  // fixing padding when the error is on the first character
76✔
125
                    // underline the error in red
126
                    fmt::styled("^", colorize ? fmt::fg(fmt::color::red) : fmt::text_style()),
76✔
127
                    col_end - curr_col_start);
76✔
128
            }
76✔
129
        }
169✔
130
    }
68✔
131

132
    template <typename T>
133
    void helper(std::ostream& os, const std::string& message, const bool colorize, const std::string& filename, const std::string& code, const T& expr,
73✔
134
                const std::size_t line, std::size_t column, const std::size_t sym_size)
135
    {
73✔
136
        if (filename != ARK_NO_NAME_FILE)
73✔
137
            fmt::print(os, "In file {}\n", filename);
73✔
138
        fmt::print(os, "At {} @ {}:{}\n", expr, line + 1, column);
73✔
139

140
        if (!code.empty())
73✔
141
            makeContext(os, code, line, column, sym_size, colorize);
68✔
142

143
        const auto message_lines = Utils::splitString(message, '\n');
73✔
144
        for (const auto& text : message_lines)
147✔
145
            fmt::print(os, "        {}\n", text);
74✔
146
    }
73✔
147

148
    std::string makeContextWithNode(const std::string& message, const internal::Node& node)
×
149
    {
×
150
        std::stringstream ss;
×
151

152
        std::size_t size = 3;
×
153
        // todo add "can be string" attribute
154
        if (node.nodeType() == internal::NodeType::Symbol || node.nodeType() == internal::NodeType::String || node.nodeType() == internal::NodeType::Spread)
×
155
            size = node.string().size();
×
156

157
        helper(
×
158
            ss,
×
159
            message,
×
160
            true,
161
            node.filename(),
×
162
            (node.filename() == ARK_NO_NAME_FILE) ? "" : Utils::readFile(node.filename()),
×
163
            node.repr(),
×
164
            node.line(),
×
165
            node.col(),
×
166
            size);
×
167

168
        return ss.str();
×
169
    }
×
170

171
    void generate(const CodeError& e, std::ostream& os, bool colorize)
73✔
172
    {
73✔
173
        if (const char* nocolor = std::getenv("NOCOLOR"); nocolor != nullptr)
73✔
174
            colorize = false;
×
175

176
        std::string escaped_symbol;
73✔
177
        if (e.symbol.has_value())
73✔
178
        {
179
            switch (e.symbol.value().codepoint())
28✔
180
            {
×
181
                case '\n': escaped_symbol = "'\\n'"; break;
×
182
                case '\r': escaped_symbol = "'\\r'"; break;
×
183
                case '\t': escaped_symbol = "'\\t'"; break;
×
184
                case '\v': escaped_symbol = "'\\v'"; break;
9✔
185
                case '\0': escaped_symbol = "EOF"; break;
11✔
186
                case ' ': escaped_symbol = "' '"; break;
19✔
187
                default:
188
                    escaped_symbol = e.symbol.value().c_str();
17✔
189
            }
28✔
190
        }
28✔
191
        else
192
            escaped_symbol = e.expr;
45✔
193

194
        std::string file_content;
73✔
195
        if (e.filename != ARK_NO_NAME_FILE)
73✔
196
            file_content = Utils::readFile(e.filename);
73✔
197

198
        // TODO enhance the error messages
199
        helper(
219✔
200
            os,
73✔
201
            e.what(),
73✔
202
            colorize,
73✔
203
            e.filename,
73✔
204
            file_content,
205
            escaped_symbol,
206
            e.line,
73✔
207
            e.col,
73✔
208
            e.expr.size());
73✔
209
    }
73✔
210
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc