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

ArkScript-lang / Ark / 12164232004

04 Dec 2024 04:37PM UTC coverage: 77.815% (+0.6%) from 77.19%
12164232004

push

github

SuperFola
feat(name resolution): allow fqn if the scope is only exporting symbols

1 of 3 new or added lines in 2 files covered. (33.33%)

256 existing lines in 11 files now uncovered.

5412 of 6955 relevant lines covered (77.81%)

9300.67 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
84✔
18
    {
19
        int open_parentheses = 0;
84✔
20
        int open_square_braces = 0;
84✔
21
        int open_curly_braces = 0;
84✔
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)
84✔
87
    {
84✔
88
        using namespace Ark::literals;
89

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

94
        const std::size_t first_line = target_line >= 3 ? target_line - 3 : 0;
84✔
95
        const std::size_t last_line = (target_line + 3) <= ctx.size() ? target_line + 3 : ctx.size();
84✔
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
84✔
97
        LineColorContextCounts line_color_context_counts;
84✔
98

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

108
            if (i == target_line || (i > target_line && overflow > 0))
206✔
109
            {
110
                fmt::print(os, "      |");
92✔
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;
92✔
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())
100✔
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;
92✔
118

119
                fmt::print(
276✔
120
                    os,
92✔
121
                    "{: <{}}{:~<{}}\n",
92✔
122
                    // padding of spaces
123
                    " ",
124
                    std::max(1_z, curr_col_start),  // fixing padding when the error is on the first character
92✔
125
                    // underline the error in red
126
                    fmt::styled("^", colorize ? fmt::fg(fmt::color::red) : fmt::text_style()),
92✔
127
                    col_end - curr_col_start);
92✔
128
            }
92✔
129
        }
206✔
130
    }
84✔
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,
87✔
134
                const std::size_t line, std::size_t column, const std::size_t sym_size)
135
    {
87✔
136
        if (filename != ARK_NO_NAME_FILE)
87✔
137
            fmt::print(os, "In file {}\n", filename);
87✔
138
        fmt::print(os, "At {} @ {}:{}\n", expr, line + 1, column);
87✔
139

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

143
        const auto message_lines = Utils::splitString(message, '\n');
87✔
144
        for (const auto& text : message_lines)
175✔
145
            fmt::print(os, "        {}\n", text);
88✔
146
    }
87✔
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;
×
UNCOV
153
        if (node.isStringLike())
×
154
            size = node.string().size();
×
155

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

UNCOV
167
        return ss.str();
×
168
    }
×
169

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

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

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

197
        // TODO enhance the error messages
198
        helper(
261✔
199
            os,
87✔
200
            e.what(),
87✔
201
            colorize,
87✔
202
            e.filename,
87✔
203
            file_content,
204
            escaped_symbol,
205
            e.line,
87✔
206
            e.col,
87✔
207
            e.expr.size());
87✔
208
    }
87✔
209
}
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