4
Copyright (c) 2021 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,
6
https://bmstu.codes/lsx/simodo
9
/*! \file Утилита тестирования средств работы с JSON библиотеки SIMODO core. Проект SIMODO.
12
#include "simodo/lsp-server/ServerContext.h"
13
#include "simodo/lsp-server/DocumentContext.h"
15
#include "simodo/lsp-client/LspEnums.h"
17
#include "simodo/variable/json/parser/JsonRdp.h"
18
#include "simodo/variable/json/parser/Json5Rdp.h"
19
#include "simodo/variable/json/parser/JsonLspBuilder.h"
20
#include "simodo/inout/log/Logger.h"
21
#include "simodo/inout/token/RefBufferStream.h"
22
#include "simodo/inout/convert/functions.h"
23
#include "simodo/variable/json/Serialization.h"
30
using namespace simodo;
32
class JsonDocumentOperation : public lsp::DocumentOperation_interface
34
lsp::DocumentContext & _doc;
36
std::vector<inout::Token> _const_variable_set;
37
std::vector<std::pair<inout::Token,inout::Token>>
41
JsonDocumentOperation(lsp::DocumentContext &doc) : _doc(doc) {}
43
virtual bool analyze(const std::u16string & text, inout::Reporter_abstract & m) override
45
if (_doc.file_name().empty())
48
std::vector<inout::Token> const_variable_set;
49
std::vector<std::pair<inout::Token,inout::Token>>
51
variable::JsonLspBuilder builder(const_variable_set, group_set);
52
inout::RefBufferStream buffer_stream(text.data());
53
std::unique_ptr<inout::Parser_interface>
55
variable::Value value;
58
if (_doc.file_name()[_doc.file_name().size()-1] == '5')
59
parser = std::make_unique<variable::Json5Rdp>(m, builder, _doc.file_name(), value);
61
parser = std::make_unique<variable::JsonRdp>(m, builder, _doc.file_name(), value);
65
ok = parser->parse(buffer_stream);
67
catch(const std::exception & ex)
69
m.reportFatal(ex.what());
72
if (ok || const_variable_set.size() >= _const_variable_set.size()) {
73
std::sort(group_set.begin(),
75
[](const std::pair<inout::Token,inout::Token> & a, const std::pair<inout::Token,inout::Token> & b)
77
return a.first.location().range().start() < b.first.location().range().start();
80
_const_variable_set.swap(const_variable_set);
81
_group_set.swap(group_set);
87
virtual bool checkDependency(const std::string & /*uri*/) const override
92
virtual variable::Value produceHoverResponse(const lsp::Position & /*pos*/) const override
97
virtual variable::Value produceGotoDeclarationResponse(const lsp::Position & /*pos*/) const override
102
virtual variable::Value produceGotoDefinitionResponse(const lsp::Position & /*pos*/) const override
107
virtual variable::Value produceCompletionResponse(const lsp::CompletionParams & /*completionParams*/) const override
112
virtual variable::Value produceSemanticTokensResponse() const override
114
struct TokenInfo { int64_t length, type, modifiers; };
116
bool operator() (const std::pair<int64_t,int64_t> & x1, const std::pair<int64_t,int64_t> & x2) const {
117
return x1.first < x2.first || (x1.first == x2.first && x1.second < x2.second);
121
std::map<std::pair<int64_t,int64_t>, TokenInfo, TokenComp> tokens;
123
for(const inout::Token & t : _const_variable_set)
124
if (t.type() == inout::LexemeType::Id) {
125
int64_t line = static_cast<int64_t>(t.location().range().start().line());
126
int64_t character = static_cast<int64_t>(t.location().range().start().character());
127
int64_t length = static_cast<int64_t>(t.location().range().end().character()-character);
128
int64_t modifiers = static_cast<int64_t>(0);
129
tokens.insert({ {line, character}, {length, 0, modifiers}});
132
std::vector<variable::Value> sem_tokens;
134
for(const auto & [p,t] : tokens) {
135
sem_tokens.emplace_back(p.first);
136
sem_tokens.emplace_back(p.second);
137
sem_tokens.emplace_back(t.length);
138
sem_tokens.emplace_back(t.type);
139
sem_tokens.emplace_back(t.modifiers);
142
return variable::Object {{{u"data", sem_tokens}}};
145
virtual variable::Value produceDocumentSymbolsResponse() const override
147
std::vector<variable::Value> doc_symbols;
149
for(const inout::Token & t : _const_variable_set)
150
if (t.type() == inout::LexemeType::Id) {
151
doc_symbols.emplace_back(variable::Object {{
152
{u"name", t.token()},
153
{u"detail", t.token()
154
+ u" [" + inout::toU16(std::to_string(t.location().range().start().line()+1))
155
+ u"," + inout::toU16(std::to_string(t.location().range().start().character()+1))
157
{u"kind", int64_t(lsp::SymbolKind::Variable)},
158
{u"range", _doc.makeRange({t.location().range().start(), t.location().range().end()})},
159
{u"selectionRange", _doc.makeRange(t.location().range())},
166
virtual variable::Value produceSimodoCommandResponse(const std::u16string & /*command_name*/, std::u16string /*text*/) const override
172
class DocumentOperationFactory : public lsp::DocumentOperationFactory_interface
175
virtual std::unique_ptr<lsp::DocumentOperation_interface> create(lsp::DocumentContext &doc, const std::string & /*languageId*/)
177
return std::make_unique<JsonDocumentOperation>(doc);
181
int main(int argc, char *argv[])
183
inout::Logger::SeverityLevel log_level = inout::Logger::SeverityLevel::Info;
184
bool save_mode = false;
185
std::unique_ptr<std::ostream> log_stream;
186
std::unique_ptr<std::istream> in;
189
log_stream = std::make_unique<std::ofstream>(argv[1]);
193
if (std::string(argv[2]) == "Debug")
194
log_level = inout::Logger::SeverityLevel::Debug;
195
else if (std::string(argv[2]) == "Info")
196
log_level = inout::Logger::SeverityLevel::Info;
197
else if (std::string(argv[2]) == "Warning")
198
log_level = inout::Logger::SeverityLevel::Warning;
199
else if (std::string(argv[2]) == "Error")
200
log_level = inout::Logger::SeverityLevel::Error;
201
else if (std::string(argv[2]) == "Critical")
202
log_level = inout::Logger::SeverityLevel::Critical;
206
save_mode = std::string(argv[3]) == "save";
210
in = std::make_unique<std::ifstream>(simodo::inout::fromUtf8CharToWChar(argv[4]).c_str());
212
in = std::make_unique<std::ifstream>(argv[4]);
214
inout::Logger log(log_stream ? *log_stream.get() : std::cerr,
218
lsp::ServerCapabilities server_capabilities;
220
server_capabilities.hoverProvider = false;
221
server_capabilities.documentSymbolProvider = true;
222
server_capabilities.semanticTokensProvider.legend.tokenTypes = {u"property"};
224
DocumentOperationFactory factory;
226
lsp::ServerContext server(u"JSON",
228
lsp::SimodoCapabilities(),
231
in ? *in.get() : std::cin,