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

ArkScript-lang / Ark / 17410180849

02 Sep 2025 04:42PM UTC coverage: 90.848% (-0.005%) from 90.853%
17410180849

push

github

SuperFola
feat(vm): adding new super instruction AT_SYM_INDEX_CONST, to load a value from a container using a constant as the index

5 of 5 new or added lines in 2 files covered. (100.0%)

6 existing lines in 3 files now uncovered.

7931 of 8730 relevant lines covered (90.85%)

156927.33 hits per line

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

94.79
/src/arkreactor/Compiler/NameResolution/ScopeResolver.cpp
1
#include <Ark/Compiler/NameResolution/ScopeResolver.hpp>
2

3
#include <ranges>
4
#include <algorithm>
5

6
namespace Ark::internal
7
{
8
    ScopeResolver::ScopeResolver()
332✔
9
    {
332✔
10
        createNewNamespace("", /* with_prefix= */ false, /* is_glob= */ true, /* symbols= */ {});
332✔
11
    }
332✔
12

13
    void ScopeResolver::createNew()
10,897✔
14
    {
10,897✔
15
        m_scopes.emplace_back(std::make_unique<StaticScope>());
10,897✔
16
    }
10,897✔
17

18
    void ScopeResolver::removeLastScope()
10,895✔
19
    {
10,895✔
20
        m_scopes.pop_back();
10,895✔
21
    }
10,895✔
22

23
    void ScopeResolver::createNewNamespace(const std::string& name, bool with_prefix, bool is_glob, const std::vector<std::string>& symbols)
523✔
24
    {
523✔
25
        m_scopes.emplace_back(std::make_unique<NamespaceScope>(name, with_prefix, is_glob, symbols));
523✔
26
    }
523✔
27

28
    std::string ScopeResolver::registerInCurrent(const std::string& name, const bool is_mutable)
30,273✔
29
    {
30,273✔
30
        return m_scopes.back()->add(name, is_mutable);
30,273✔
31
    }
32

33
    void ScopeResolver::saveNamespaceAndRemove()
189✔
34
    {
189✔
35
        for (auto& m_scope : std::ranges::reverse_view(m_scopes) | std::ranges::views::drop(1))
378✔
36
        {
37
            if (m_scope->saveNamespace(m_scopes.back()))
189✔
38
                break;
189✔
39
        }
189✔
40

41
        m_scopes.pop_back();
189✔
42
    }
189✔
43

44
    std::optional<bool> ScopeResolver::isImmutable(const std::string& name) const
4,905✔
45
    {
4,905✔
46
        for (const auto& m_scope : std::ranges::reverse_view(m_scopes))
14,542✔
47
        {
48
            if (auto maybe = m_scope->get(name, currentNamespace(), true); maybe.has_value())
14,542✔
49
                return !maybe.value().is_mutable;
4,905✔
50
        }
9,637✔
51
        return std::nullopt;
×
52
    }
4,905✔
53

54
    bool ScopeResolver::isRegistered(const std::string& name) const
4,916✔
55
    {
4,916✔
56
        const std::string origin_namespace = currentNamespace();
4,916✔
57
        return std::ranges::any_of(std::ranges::reverse_view(m_scopes), [&name, &origin_namespace](const auto& scope) {
14,627✔
58
            return scope->get(name, origin_namespace, true).has_value();
9,711✔
59
        });
60
    }
4,916✔
61

62
    bool ScopeResolver::isInScope(const std::string& name) const
20,284✔
63
    {
20,284✔
64
        return m_scopes.back()->get(name, currentNamespace(), false).has_value();
20,284✔
UNCOV
65
    }
×
66

67
    std::string ScopeResolver::getFullyQualifiedNameInNearestScope(const std::string& name) const
92,752✔
68
    {
92,752✔
69
        const std::string prefix = currentNamespace();
92,752✔
70
        std::optional<std::string> maybe_name;
92,752✔
71
        for (const auto& scope : std::ranges::reverse_view(m_scopes))
465,397✔
72
        {
73
            if (auto maybe_fqn = scope->get(name, prefix, true); maybe_fqn.has_value())
428,513✔
74
            {
75
                // prioritize non-hidden symbols
76
                if ((maybe_name.has_value() &&
59,554✔
77
                     maybe_name.value().ends_with("#hidden") &&
1,843✔
78
                     !maybe_fqn.value().name.ends_with("#hidden")) ||
1✔
79
                    !maybe_name.has_value())
55,868✔
80
                    maybe_name = maybe_fqn.value().name;
54,025✔
81
            }
55,868✔
82
        }
372,645✔
83
        return maybe_name.value_or(name);
92,752✔
84
    }
92,752✔
85

86
    std::pair<bool, std::string> ScopeResolver::canFullyQualifyName(const std::string& name)
88,102✔
87
    {
88,102✔
88
        // a given name can be fully qualified if
89
        // old == new
90
        // old != new and new has prefix
91
        //     if the prefix namespace is glob
92
        //     if the prefix namespace has name in its symbols
93
        //     if the prefix namespace is with_prefix && it is the top most scope
94
        const std::string maybe_fqn = getFullyQualifiedNameInNearestScope(name);
88,102✔
95

96
        if (maybe_fqn == name)
88,102✔
97
            return std::make_pair(true, maybe_fqn);
86,623✔
98

99
        const std::string prefix = maybe_fqn.substr(0, maybe_fqn.find_first_of(':'));
1,479✔
100
        const std::string unprefixed_name = name.substr(name.find_first_of(':') + 1);
1,479✔
101
        auto namespaces =
1,479✔
102
            std::ranges::reverse_view(m_scopes) | std::ranges::views::filter([](const auto& e) {
4,579✔
103
                return e->isNamespace();
3,100✔
104
            });
105
        bool top = true;
1,479✔
106
        for (auto& scope : namespaces)
2,961✔
107
        {
108
            if (top && prefix == scope->prefix())
1,482✔
109
                return std::make_pair(true, maybe_fqn);
1,380✔
110
            if (!top && prefix == scope->prefix() && (scope->isGlob() || scope->hasSymbol(name)))
102✔
UNCOV
111
                return std::make_pair(true, maybe_fqn);
×
112

113
            // check for the presence of the symbol in symbol imports and glob imports
114
            if (scope->recursiveHasSymbol(unprefixed_name))
102✔
115
                return std::make_pair(true, maybe_fqn);
98✔
116

117
            top = false;
4✔
118
        }
1,482✔
119

120
        return std::make_pair(false, maybe_fqn);
1✔
121
    }
88,102✔
122

123
    StaticScope* ScopeResolver::currentScope() const
191✔
124
    {
191✔
125
        if (!m_scopes.empty()) [[likely]]
191✔
126
            return m_scopes.back().get();
191✔
UNCOV
127
        return nullptr;
×
128
    }
191✔
129

130
    std::string ScopeResolver::currentNamespace() const
127,589✔
131
    {
127,589✔
132
        for (const auto& scope : std::ranges::reverse_view(m_scopes))
433,838✔
133
        {
134
            if (scope->isNamespace())
306,249✔
135
                return scope->prefix();
127,589✔
136
        }
306,249✔
137

138
        // no namespace name, thus no prefix ; "" is either the default namespace, a function scope or a while loop
UNCOV
139
        return "";
×
140
    }
127,589✔
141
}
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