4
#include "ScriptDocumentOperation.h"
6
#if __cplusplus >= __cpp_2017
8
namespace fs = std::filesystem;
10
#include <experimental/filesystem>
11
namespace fs = std::filesystem::experimental;
14
using namespace simodo;
16
ScriptDocumentOperation::ScriptDocumentOperation(lsp::DocumentContext &doc,
17
const DocumentOperationFactory & factory,
18
std::string languageId)
21
, _languageId(std::move(languageId))
25
bool ScriptDocumentOperation::checkDependency(const std::string & uri) const
27
const auto & contains = [&uri](const std::string & file) { return uri == file; };
29
return std::ranges::any_of(_files, contains);
32
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
34
bool ScriptDocumentOperation::isRemoteFunctionLaunch(const inout::TokenLocation & using_location) const {
35
const auto & IsRangeEqual = [](const inout::TokenLocation & target_location)
37
return [&target_location] (const inout::TokenLocation & given_location) { return given_location.range() == target_location.range(); };
40
return std::ranges::any_of(_semantic_data.remotes(), IsRangeEqual(using_location));
44
lsp::Range ScriptDocumentOperation::getFunctionBodyRange(const variable::Variable & var) {
45
assert(var.type() == variable::ValueType::Function);
47
const auto function_object = var.value().getObject();
48
const auto & function_parameters = function_object->variables();
50
assert(function_parameters[0].type() == variable::ValueType::IntFunction);
51
const auto &[code, closures, parent] = function_parameters[0].value().getIntFunction();
53
assert(!code->branches().empty());
55
assert(int(code->operation()) == 3107);
57
const auto & openBracketToken = code->token();
58
const auto & closeBracketToken = code->branches().back().token();
60
assert(openBracketToken.location().range().start() <= closeBracketToken.location().range().end());
62
return { openBracketToken.location().range().start(), closeBracketToken.location().range().end() };
66
/// Шаблонная функция превращения некоторых предметов через заданную функцию и разделитель в строку
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", ") {
74
for (auto it = begin; it != end; ++it) {
75
if (it != begin) text += delimiter;
84
std::u16string getValueTypeName(const variable::ValueType type) {
86
case variable::ValueType::Null:
89
return inout::toU16(variable::getValueTypeName(type));
93
inline std::u16string getVariableName(const variable::Variable & var) { return var.name(); }
95
/// Базовое преобразование переменной в текст, подобный исходному коду, содержащий тип и имя.
96
/// Например, "int : x".
97
inline std::u16string getVariableBaseString(const variable::Variable & var) {
98
return ::getValueTypeName(var.type()) + u" : " + getVariableName(var);
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);
107
const auto function_object = var.value().getObject();
108
const auto & function_parameters = function_object->variables();
110
const auto & function_return_type = function_parameters[1].value().type();
111
const auto & function_return_type_string = ::getValueTypeName(function_return_type);
113
const auto & params_string = join<variable::Variable>(function_parameters.begin() + 2, function_parameters.end(), getVariableBaseString);
115
assert(function_parameters[0].type() == variable::ValueType::IntFunction
116
|| function_parameters[0].type() == variable::ValueType::ExtFunction);
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();
122
if (const auto & closures_parameters = closures.variables(); not closures_parameters.empty()) {
123
// \todo Сделать проверку на замыкания типа "[*]", check/031-14-FunctionDefinition
125
const auto & closures_parameters_string =
126
join<variable::Variable>(closures_parameters.begin(), closures_parameters.end(), getVariableName);
128
closures_string = u" [" + closures_parameters_string + u"]";
132
return u"fn " + var.name() + closures_string + u" (" + params_string + u")" + u" -> " + function_return_type_string;
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;
145
std::u16string ScriptDocumentOperation::getVariableString(const variable::Variable & var) {
148
if (var.type() == variable::ValueType::Function) {
149
text = getFunctionString(var);
151
text = getVariableBaseString(var);
152
if (isPrimitiveType(var.type()))
153
text += u" = " + variable::toString(var.value());