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

ArkScript-lang / Ark / 14647441324

24 Apr 2025 05:07PM UTC coverage: 83.165% (+2.7%) from 80.417%
14647441324

push

github

SuperFola
feat(vm): compressing identical traces when displaying the stacktrace of an error

21 of 21 new or added lines in 1 file covered. (100.0%)

270 existing lines in 10 files now uncovered.

6580 of 7912 relevant lines covered (83.16%)

79046.5 hits per line

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

87.6
/src/arkreactor/TypeChecker.cpp
1
#include <Ark/TypeChecker.hpp>
2

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

10
namespace Ark::types
11
{
12
    std::string typeListToString(const std::vector<ValueType>& types)
85✔
13
    {
85✔
14
        if (types.size() == 1 && types[0] == ValueType::Any)
85✔
15
            return "any";
4✔
16

17
        std::string acc;
81✔
18

19
        for (std::size_t i = 0, end = types.size(); i < end; ++i)
163✔
20
        {
21
            if (i > 0)
82✔
22
                acc += ", ";
1✔
23
            acc += types_to_str[static_cast<std::size_t>(types[i])];
82✔
24
        }
82✔
25
        return acc;
81✔
26
    }
166✔
27

28
    void displayContract(const Contract& contract, const std::vector<Value>& args, std::ostream& os, const bool colorize)
46✔
29
    {
46✔
30
        auto displayArg = [colorize, &os](const Typedef& td, const bool correct) {
131✔
31
            const std::string arg_str = typeListToString(td.types);
85✔
32

33
            fmt::dynamic_format_arg_store<fmt::format_context> store;
85✔
34
            store.push_back(td.variadic ? "variadic " : "");
85✔
35
            if (colorize)
85✔
UNCOV
36
                store.push_back(
×
UNCOV
37
                    fmt::styled(
×
38
                        td.name,
×
39
                        correct
×
40
                            ? fmt::fg(fmt::color::green)
×
41
                            : fmt::fg(fmt::color::magenta)));
×
42
            else
43
                store.push_back(td.name);
85✔
44
            store.push_back(arg_str);
85✔
45

46
            fmt::vprint(os, "  -> {}{} ({})", store);
85✔
47
        };
85✔
48

49
        for (std::size_t i = 0, end = contract.arguments.size(); i < end; ++i)
131✔
50
        {
51
            const Typedef& td = contract.arguments[i];
85✔
52

53
            if (td.variadic && i < args.size())
85✔
54
            {
55
                // variadic argument in contract and enough provided arguments
56
                std::size_t bad_type = 0;
1✔
57
                for (std::size_t j = i, args_end = args.size(); j < args_end; ++j)
3✔
58
                {
59
                    if (td.types[0] != ValueType::Any && std::ranges::find(td.types, args[j].valueType()) == td.types.end())
2✔
60
                        bad_type++;
1✔
61
                }
2✔
62

63
                if (bad_type)
1✔
64
                {
65
                    displayArg(td, /* correct= */ false);
1✔
66

67
                    fmt::dynamic_format_arg_store<fmt::format_context> store;
1✔
68
                    if (colorize)
1✔
UNCOV
69
                        store.push_back(fmt::styled(bad_type, fmt::fg(fmt::color::red)));
×
70
                    else
71
                        store.push_back(bad_type);
1✔
72
                    store.push_back(bad_type > 1 ? "s" : "");
1✔
73

74
                    fmt::vprint(os, " {} argument{} do not match", store);
1✔
75
                }
1✔
76
                else
UNCOV
77
                    displayArg(td, /* correct= */ true);
×
78
            }
1✔
79
            else
80
            {
81
                // provided argument but wrong type
82
                if (i < args.size() && td.types[0] != ValueType::Any && std::ranges::find(td.types, args[i].valueType()) == td.types.end())
84✔
83
                {
84
                    displayArg(td, /* correct= */ false);
45✔
85
                    const auto type = types_to_str[static_cast<std::size_t>(args[i].valueType())];
45✔
86

87
                    fmt::dynamic_format_arg_store<fmt::format_context> store;
45✔
88
                    if (colorize)
45✔
UNCOV
89
                        store.push_back(fmt::styled(type, fmt::fg(fmt::color::red)));
×
90
                    else
91
                        store.push_back(type);
45✔
92
                    fmt::vprint(os, " was of type {}", store);
45✔
93
                }
45✔
94
                // non-provided argument
95
                else if (i >= args.size())
39✔
96
                {
97
                    displayArg(td, /* correct= */ false);
6✔
98
                    if (colorize)
6✔
UNCOV
99
                        fmt::print(os, "{}", fmt::styled(" was not provided", fmt::fg(fmt::color::red)));
×
100
                    else
101
                        fmt::print(os, " was not provided");
6✔
102
                }
6✔
103
                else
104
                    displayArg(td, /* correct= */ true);
33✔
105
            }
106
            fmt::print(os, "\n");
85✔
107
        }
85✔
108
    }
46✔
109

110
    void generateError(const std::string_view& funcname, const std::vector<Contract>& contracts, const std::vector<Value>& args, std::ostream& os, bool colorize)
35✔
111
    {
35✔
112
        {
113
            fmt::dynamic_format_arg_store<fmt::format_context> store;
35✔
114
            if (colorize)
35✔
UNCOV
115
                store.push_back(fmt::styled(funcname, fmt::fg(fmt::color::blue)));
×
116
            else
117
                store.push_back(funcname);
35✔
118
            fmt::vprint(os, "Function {} expected ", store);
35✔
119
        }
35✔
120

121
        std::vector<Value> sanitizedArgs;
35✔
122
        std::ranges::copy_if(args, std::back_inserter(sanitizedArgs), [](const Value& value) -> bool {
97✔
123
            return value.valueType() != ValueType::Undefined;
62✔
124
        });
125

126
        // get expected arguments count
127
        std::size_t min_argc = std::numeric_limits<std::size_t>::max(), max_argc = 0;
35✔
128
        for (const auto& [arguments] : contracts)
198✔
129
        {
130
            if (arguments.size() < min_argc)
46✔
131
                min_argc = arguments.size();
35✔
132
            if (arguments.size() > max_argc)
46✔
133
                max_argc = arguments.size();
36✔
134
        }
46✔
135

136
        bool correct_argcount = true;
35✔
137

138
        if (min_argc != max_argc)
35✔
139
        {
140
            fmt::dynamic_format_arg_store<fmt::format_context> store;
1✔
141
            if (colorize)
1✔
UNCOV
142
                store.push_back(fmt::styled(min_argc, fmt::fg(fmt::color::yellow)));
×
143
            else
144
                store.push_back(min_argc);
1✔
145
            store.push_back(min_argc > 1 ? "s" : "");
1✔
146
            if (colorize)
1✔
UNCOV
147
                store.push_back(fmt::styled(max_argc, fmt::fg(fmt::color::yellow)));
×
148
            else
149
                store.push_back(max_argc);
1✔
150
            store.push_back(max_argc > 1 ? "s" : "");
1✔
151

152
            fmt::vprint(os, "between {} argument{} and {} argument{}", store);
1✔
153

154
            if (sanitizedArgs.size() < min_argc || sanitizedArgs.size() > max_argc)
1✔
155
                correct_argcount = false;
1✔
156
        }
1✔
157
        else
158
        {
159
            fmt::dynamic_format_arg_store<fmt::format_context> store;
34✔
160
            if (colorize)
34✔
UNCOV
161
                store.push_back(fmt::styled(min_argc, fmt::fg(fmt::color::yellow)));
×
162
            else
163
                store.push_back(min_argc);
34✔
164
            store.push_back(min_argc > 1 ? "s" : "");
34✔
165

166
            fmt::vprint(os, "{} argument{}", store);
34✔
167

168
            if (sanitizedArgs.size() != min_argc)
34✔
169
                correct_argcount = false;
4✔
170
        }
34✔
171

172
        if (!correct_argcount)
35✔
173
        {
174
            if (colorize)
5✔
UNCOV
175
                fmt::print(os, " but got {}", fmt::styled(sanitizedArgs.size(), fmt::fg(fmt::color::red)));
×
176
            else
177
                fmt::print(os, " but got {}", sanitizedArgs.size());
5✔
178
        }
5✔
179

180
        fmt::print(os, "\n");
35✔
181

182
        displayContract(contracts[0], sanitizedArgs, os, colorize);
35✔
183
        for (std::size_t i = 1, end = contracts.size(); i < end; ++i)
46✔
184
        {
185
            fmt::print(os, "Alternative {}:\n", i + 1);
11✔
186
            displayContract(contracts[i], sanitizedArgs, os, colorize);
11✔
187
        }
11✔
188
    }
35✔
189
}
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

© 2026 Coveralls, Inc