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

ArkScript-lang / Ark / 14823373998

04 May 2025 05:03PM UTC coverage: 86.442% (+0.03%) from 86.409%
14823373998

push

github

SuperFola
fix: change the color of the function name inside runtime typechecking errors from blue to cyan to be easier to read inside dark terminals

0 of 1 new or added line in 1 file covered. (0.0%)

195 existing lines in 22 files now uncovered.

6835 of 7907 relevant lines covered (86.44%)

79668.53 hits per line

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

88.89
/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)
149✔
13
    {
149✔
14
        if (types.size() == 1 && types[0] == ValueType::Any)
149✔
15
            return "any";
12✔
16

17
        std::string acc;
137✔
18

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

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

33
            fmt::dynamic_format_arg_store<fmt::format_context> store;
149✔
34
            store.push_back(td.variadic ? "variadic " : "");
149✔
35
            if (colorize)
149✔
36
                store.push_back(
×
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);
149✔
44
            store.push_back(arg_str);
149✔
45

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

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

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

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

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

74
                    fmt::vprint(os, " {} argument{} do not match", store);
3✔
75
                }
3✔
76
                else
77
                    displayArg(td, /* correct= */ true);
2✔
78
            }
5✔
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())
144✔
83
                {
84
                    displayArg(td, /* correct= */ false);
89✔
85
                    const auto type = types_to_str[static_cast<std::size_t>(args[i].valueType())];
89✔
86

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

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

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

126
        // get expected arguments count
127
        std::size_t min_argc = std::numeric_limits<std::size_t>::max(), max_argc = 0;
76✔
128
        bool variadic = false;
76✔
129
        for (const auto& [arguments] : contracts)
582✔
130
        {
131
            if (arguments.size() < min_argc)
88✔
132
                min_argc = arguments.size();
76✔
133
            if (arguments.size() > max_argc)
88✔
134
                max_argc = arguments.size();
78✔
135

136
            if (!arguments.empty() && arguments.back().variadic)
88✔
137
                variadic = true;
6✔
138
        }
88✔
139

140
        bool correct_argcount = true;
76✔
141

142
        if (min_argc != max_argc)
76✔
143
        {
144
            fmt::dynamic_format_arg_store<fmt::format_context> store;
2✔
145
            if (colorize)
2✔
UNCOV
146
                store.push_back(fmt::styled(min_argc, fmt::fg(fmt::color::yellow)));
×
147
            else
148
                store.push_back(min_argc);
2✔
149
            store.push_back(min_argc > 1 ? "s" : "");
2✔
150
            if (colorize)
2✔
UNCOV
151
                store.push_back(fmt::styled(max_argc, fmt::fg(fmt::color::yellow)));
×
152
            else
153
                store.push_back(max_argc);
2✔
154
            store.push_back(max_argc > 1 ? "s" : "");
2✔
155

156
            fmt::vprint(os, "between {} argument{} and {} argument{}", store);
2✔
157

158
            if (sanitizedArgs.size() < min_argc || sanitizedArgs.size() > max_argc)
2✔
159
                correct_argcount = false;
2✔
160
        }
2✔
161
        else
162
        {
163
            fmt::dynamic_format_arg_store<fmt::format_context> store;
74✔
164
            store.push_back(variadic ? "at least " : "");
74✔
165
            if (colorize)
74✔
UNCOV
166
                store.push_back(fmt::styled(min_argc, fmt::fg(fmt::color::yellow)));
×
167
            else
168
                store.push_back(min_argc);
74✔
169
            store.push_back(min_argc > 1 ? "s" : "");
74✔
170

171
            fmt::vprint(os, "{}{} argument{}", store);
74✔
172

173
            if (sanitizedArgs.size() != min_argc)
74✔
174
                correct_argcount = false;
9✔
175
        }
74✔
176

177
        if (!correct_argcount || variadic)
76✔
178
        {
179
            std::string preposition = (variadic && args.size() >= min_argc) ? "and" : "but";
15✔
180
            if (colorize)
15✔
UNCOV
181
                fmt::print(os, " {} got {}", preposition, fmt::styled(sanitizedArgs.size(), fmt::fg(fmt::color::red)));
×
182
            else
183
                fmt::print(os, " {} got {}", preposition, sanitizedArgs.size());
15✔
184
        }
15✔
185

186
        fmt::print(os, "\n");
76✔
187

188
        displayContract(contracts[0], sanitizedArgs, os, colorize);
76✔
189
        for (std::size_t i = 1, end = contracts.size(); i < end; ++i)
88✔
190
        {
191
            fmt::print(os, "Alternative {}:\n", i + 1);
12✔
192
            displayContract(contracts[i], sanitizedArgs, os, colorize);
12✔
193
        }
12✔
194
    }
76✔
195
}
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