loom

Форк
0
/
ScriptDocumentOperation.cpp 
157 строк · 6.2 Кб
1
#include <cassert>
2

3

4
#include "ScriptDocumentOperation.h"
5

6
#if __cplusplus >= __cpp_2017
7
#include <filesystem>
8
namespace fs = std::filesystem;
9
#else
10
#include <experimental/filesystem>
11
namespace fs = std::filesystem::experimental;
12
#endif
13

14
using namespace simodo;
15

16
ScriptDocumentOperation::ScriptDocumentOperation(lsp::DocumentContext &doc, 
17
                                                 const DocumentOperationFactory & factory,
18
                                                 std::string languageId)
19
    : _doc(doc) 
20
    , _factory(factory)
21
    , _languageId(std::move(languageId))
22
{
23
}
24

25
bool ScriptDocumentOperation::checkDependency(const std::string & uri) const
26
{
27
    const auto & contains = [&uri](const std::string & file) { return uri == file; };
28

29
    return std::ranges::any_of(_files, contains);
30
}
31

32
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
33

34
bool ScriptDocumentOperation::isRemoteFunctionLaunch(const inout::TokenLocation & using_location) const {
35
    const auto & IsRangeEqual = [](const inout::TokenLocation & target_location)
36
    {
37
        return [&target_location] (const inout::TokenLocation & given_location) { return given_location.range() == target_location.range(); };
38
    };
39

40
    return std::ranges::any_of(_semantic_data.remotes(), IsRangeEqual(using_location));
41
}
42

43

44
lsp::Range ScriptDocumentOperation::getFunctionBodyRange(const variable::Variable & var) {
45
    assert(var.type() == variable::ValueType::Function);
46

47
    const auto   function_object     = var.value().getObject();
48
    const auto & function_parameters = function_object->variables();
49

50
    assert(function_parameters[0].type() == variable::ValueType::IntFunction);
51
    const auto &[code, closures, parent] = function_parameters[0].value().getIntFunction();
52

53
    assert(!code->branches().empty());
54

55
    assert(int(code->operation()) == 3107);
56

57
    const auto & openBracketToken  = code->token();
58
    const auto & closeBracketToken = code->branches().back().token();
59

60
    assert(openBracketToken.location().range().start() <= closeBracketToken.location().range().end());
61

62
    return { openBracketToken.location().range().start(), closeBracketToken.location().range().end() };
63
}
64

65

66
/// Шаблонная функция превращения некоторых предметов через заданную функцию и разделитель в строку
67
template<typename T>
68
static std::u16string join(const typename std::vector<T>::const_iterator begin,
69
                           const typename std::vector<T>::const_iterator end,
70
                           std::function<std::u16string(const T &)> convert,
71
                           const std::u16string & delimiter = u", ") {
72
    std::u16string text;
73

74
    for (auto it = begin; it != end; ++it) {
75
        if (it != begin) text += delimiter;
76

77
        text += convert(*it);
78
    }
79

80
    return text;
81
}
82

83

84
std::u16string getValueTypeName(const variable::ValueType type) {
85
    switch (type) {
86
        case variable::ValueType::Null:
87
            return u"void";
88
        default:
89
            return inout::toU16(variable::getValueTypeName(type));
90
    }
91
}
92

93
inline std::u16string getVariableName(const variable::Variable & var) { return var.name(); }
94

95
/// Базовое преобразование переменной в текст, подобный исходному коду, содержащий тип и имя.
96
/// Например, "int : x".
97
inline std::u16string getVariableBaseString(const variable::Variable & var) {
98
    return ::getValueTypeName(var.type()) + u" : " + getVariableName(var);
99
}
100

101
/// Преобразование переменной типа ValueType::Function в текст, подобный исходному коду.
102
/// Например, "fn func(int : no) -> bool".
103
/// \attention Поддерживается только для типа ValueType::Function!
104
std::u16string getFunctionString(const variable::Variable & var) {
105
    assert(var.type() == variable::ValueType::Function);
106

107
    const auto   function_object             = var.value().getObject();
108
    const auto & function_parameters         = function_object->variables();
109

110
    const auto & function_return_type        = function_parameters[1].value().type();
111
    const auto & function_return_type_string = ::getValueTypeName(function_return_type);
112

113
    const auto & params_string = join<variable::Variable>(function_parameters.begin() + 2, function_parameters.end(), getVariableBaseString);
114

115
    assert(function_parameters[0].type() == variable::ValueType::IntFunction
116
        || function_parameters[0].type() == variable::ValueType::ExtFunction);
117

118
    std::u16string closures_string;
119
    if (function_parameters[0].type() == variable::ValueType::IntFunction) {
120
        const auto & [code, closures, parent] = function_parameters[0].value().getIntFunction();
121

122
        if (const auto & closures_parameters = closures.variables(); not closures_parameters.empty()) {
123
            // \todo Сделать проверку на замыкания типа "[*]", check/031-14-FunctionDefinition
124

125
            const auto & closures_parameters_string =
126
                    join<variable::Variable>(closures_parameters.begin(), closures_parameters.end(), getVariableName);
127

128
            closures_string = u" [" + closures_parameters_string + u"]";
129
        }
130
    }
131

132
    return u"fn " + var.name() + closures_string + u" (" + params_string + u")" + u" -> " + function_return_type_string;
133

134
}
135

136
bool ScriptDocumentOperation::isPrimitiveType(const variable::ValueType type) {
137
    // \todo Полагаю, стоит эту проверку вынести куда-то ещё
138
    return    type == variable::ValueType::Bool
139
           or type == variable::ValueType::Int
140
           or type == variable::ValueType::Null
141
           or type == variable::ValueType::Float
142
           or type == variable::ValueType::String;
143
}
144

145
std::u16string ScriptDocumentOperation::getVariableString(const variable::Variable & var) {
146
    std::u16string text;
147

148
    if (var.type() == variable::ValueType::Function) {
149
        text = getFunctionString(var);
150
    } else {
151
        text = getVariableBaseString(var);
152
        if (isPrimitiveType(var.type()))
153
            text += u" = " + variable::toString(var.value());
154
    }
155

156
    return text;
157
}
158

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.