loom

Форк
0
/
main.cpp 
316 строк · 11.0 Кб
1
#include "simodo/lsp/client/LanguageClient.h"
2
#include "simodo/inout/log/Logger.h"
3
#include "simodo/inout/token/FileStream.h"
4
#include "simodo/inout/token/LexicalParameters.h"
5
#include "simodo/inout/token/Tokenizer.h"
6
#include "simodo/inout/convert/functions.h"
7

8
#include <sstream>
9

10
using namespace simodo;
11
using namespace simodo::inout;
12

13
void performOpenCommand(lsp::LanguageClient & client, std::vector<Token> command) 
14
{
15
    // format: o uri [grammar]
16

17
    if (command.size() < 2) {
18
        std::cout << "Wrong structure of Open command" << std::endl;
19
        return;
20
    }
21

22
    std::ifstream in(toU8(command[1].lexeme()));
23
    if (!in) {
24
        std::cout << "*** Unable to open file '" << toU8(command[1].lexeme()) << "'" << std::endl;
25
        return;
26
    }
27

28
    InputStream in_stream(in);
29
    std::u16string    string_buffer;
30

31
    for(;;) {
32
        char16_t ch = in_stream.get(); 
33
        if (ch == std::char_traits<char16_t>::eof())
34
            break; 
35
        string_buffer += ch;
36
    }
37

38
    client.exec("textDocument/didOpen", variable::Object {{
39
                    {u"textDocument", variable::Object {{
40
                        {u"uri",        command[1].lexeme()},
41
                        {u"languageId", command.size() > 2 ? command[2].lexeme() : u"simodo-script"},
42
                        {u"version",    0},
43
                        {u"text",       encodeSpecialChars(string_buffer)},
44
                    }}},
45
                }});
46
}
47

48
void performCloseCommand(lsp::LanguageClient & client, std::vector<Token> command) 
49
{
50
    // format: c uri
51

52
    if (command.size() != 2) {
53
        std::cout << "*** Wrong structure of Close command" << std::endl;
54
        return;
55
    }
56

57
    client.exec("textDocument/didClose", variable::Object {{
58
                    {u"textDocument", variable::Object {{
59
                        {u"uri",        command[1].lexeme()},
60
                    }}},
61
                }});
62
}
63

64
void performChangeCommand(lsp::LanguageClient & client, std::vector<Token> command) 
65
{
66
    // format: u uri version text
67

68
    if (command.size() != 4) {
69
        std::cout << "*** Wrong structure of Change command" << std::endl;
70
        // for(const Token & t : command)
71
        //     std::cout << "'" << toU8(t.lexeme()) << "': " << toU8(getLexemeTypeName(t.type())) << std::endl;
72
        return;
73
    }
74

75
    client.exec("textDocument/didChange", variable::Object {{
76
                    {u"textDocument", variable::Object {{
77
                        {u"uri",        command[1].lexeme()},
78
                        {u"version",    int64_t(std::stol(toU8(command[2].lexeme())))},
79
                    }}},
80
                    {u"contentChanges", variable::Array {{
81
                        variable::Object {{{u"text", command[3].lexeme()}}},
82
                    }}},
83
                }});
84
}
85

86
void performHoverCommand(lsp::LanguageClient & client, std::vector<Token> command) 
87
{
88
    // format: h uri line character
89

90
    if (command.size() < 4) {
91
        std::cout << "*** Wrong structure of Hover command" << std::endl;
92
        return;
93
    }
94

95
    client.exec("textDocument/hover", 
96
                variable::Object {{
97
                    {u"textDocument", variable::Object {{
98
                        {u"uri", command[1].lexeme()},
99
                    }}},
100
                    {u"position", variable::Object {{
101
                        {u"line", int64_t(std::stol(toU8(command[2].lexeme())))},
102
                        {u"character", int64_t(std::stol(toU8(command[3].lexeme())))},
103
                    }}},
104
                }}, 
105
                [](const variable::JsonRpc & rpc, const void *){
106
                    std::cout << "= textDocument/hover => " << variable::toJson(rpc.value()) << std::endl;
107
                });
108
}
109

110
void performDefinitionCommand(lsp::LanguageClient & client, std::vector<Token> command)
111
{
112
    // format: h uri line character
113

114
    if (command.size() < 4) {
115
        std::cout << "*** Wrong structure of Definition command" << std::endl;
116
        return;
117
    }
118

119
    client.exec("textDocument/definition",
120
                variable::Object {{
121
                    {u"textDocument", variable::Object {{
122
                        {u"uri", command[1].lexeme()},
123
                    }}},
124
                    {u"position", variable::Object {{
125
                        {u"line", int64_t(std::stol(toU8(command[2].lexeme())))},
126
                        {u"character", int64_t(std::stol(toU8(command[3].lexeme())))},
127
                    }}},
128
                }},
129
                [](const variable::JsonRpc & rpc, const void *){
130
                    std::cout << "= textDocument/definition => " << variable::toJson(rpc.value()) << std::endl;
131
                });
132
}
133

134
void performDocSymbolsCommand(lsp::LanguageClient & client, std::vector<Token> command) 
135
{
136
    // format: s uri
137

138
    if (command.size() != 2) {
139
        std::cout << "*** Wrong structure of 'documentSymbol' command" << std::endl;
140
        return;
141
    }
142

143
    client.exec("textDocument/documentSymbol", 
144
                variable::Object {{
145
                    {u"textDocument", variable::Object {{
146
                        {u"uri", command[1].lexeme()},
147
                    }}},
148
                }}, 
149
                [](const variable::JsonRpc & rpc, const void *){
150
                    std::cout << "= textDocument/documentSymbol => " << variable::toJson(rpc.value()) << std::endl;
151
                });
152
}
153

154
void performSemTokensCommand(lsp::LanguageClient & client, std::vector<Token> command) 
155
{
156
    // format: t uri
157

158
    if (command.size() != 2) {
159
        std::cout << "*** Wrong structure of 'semanticTokens' command" << std::endl;
160
        return;
161
    }
162

163
    client.exec("textDocument/semanticTokens/full", 
164
                variable::Object {{
165
                    {u"textDocument", variable::Object {{
166
                        {u"uri", command[1].lexeme()},
167
                    }}},
168
                }}, 
169
                [](const variable::JsonRpc & rpc, const void *){
170
                    std::cout << "= textDocument/semanticTokens => " << variable::toJson(rpc.value()) << std::endl;
171
                });
172
}
173

174
void performSegmentationFaultCommand(lsp::LanguageClient & client, std::vector<Token> command) 
175
{
176
    // format: sf uri
177

178
    if (command.size() != 2) {
179
        std::cout << "*** Wrong structure of 'SegmentationFault' command" << std::endl;
180
        return;
181
    }
182

183
    client.exec("SegmentationFault", 
184
                variable::Object {{
185
                    {u"textDocument", variable::Object {{
186
                        {u"uri", command[1].lexeme()},
187
                    }}},
188
                }}, 
189
                [](const variable::JsonRpc & rpc, const void *){
190
                    std::cout << "= SegmentationFault => " << variable::toJson(rpc.value()) << std::endl;
191
                });
192
}
193

194
void performWaitCommand(lsp::LanguageClient & , std::vector<Token> command) 
195
{
196
    // format: w mills
197

198
    if (command.size() < 2 || command[1].type() != LexemeType::Number) {
199
        std::cout << "*** Wrong structure of Wait command" << std::endl;
200
        return;
201
    }
202

203
    int wait_mills = std::stol(toU8(command[1].lexeme()));
204
    std::this_thread::sleep_for(std::chrono::milliseconds(wait_mills));
205
}
206

207
int main(int argc, char * argv[]) 
208
{
209
    if (argc < 3) {
210
        std::cout << "Usage: language-client <command file> <path to language server> {<language server args...>}" << std::endl;
211
        return 1;
212
    }
213

214
    std::ifstream in(argv[1]);
215

216
    if (!in) {
217
        std::cout << "*** Unable to open file '" << argv[1] << "'" << std::endl;
218
        return 1;
219
    }
220

221
    Logger log(std::cout, "LSP-client", Logger::SeverityLevel::Warning);
222

223
    std::vector<std::string> args(argv+3,argv+argc);
224

225
    lsp::LanguageClient client(argv[2], args, {}, log);
226

227
    if (!client.running()) {
228
        std::cout << "*** Server don't running" << std::endl;
229
        return 1;
230
    }
231

232
    client.registerListener("textDocument/publishDiagnostics", 
233
            [&] (variable::JsonRpc rpc, const void *) {
234
                std::cout << "= textDocument/publishDiagnostics => " << variable::toJson(rpc.value()) << std::endl;
235

236
                if (rpc.params().isObject()) {
237
                    const variable::Value & uri_value = rpc.params().getObject()->find(u"uri");
238
                    if (uri_value.isString()) {
239
                        const std::u16string uri = uri_value.getString();
240
                        const inout::Token   uri_token {inout::LexemeType::Id, uri, inout::null_token_location};
241

242
                        performDocSymbolsCommand(client, {inout::null_token, uri_token});
243
                        performSemTokensCommand(client, {inout::null_token, uri_token});
244
                    }
245
                    else
246
                        std::cout << "*** uri not found" << std::endl;
247
                }
248
                else
249
                    std::cout << "*** params not found" << std::endl;
250
            });
251

252
    std::string line;
253
    while(std::getline(in,line) && !line.empty()) {
254
        std::vector<Token>   command;
255
        std::istringstream   str_in(line);
256
        InputStream          in(str_in);
257
        LexicalParameters    lex;
258
        lex.masks.push_back({ BUILDING_NUMBER, LexemeType::Number, 10 });
259
        lex.markups.push_back({u"\"", u"\"", u"\\", LexemeType::Annotation});
260
        
261
        Tokenizer            tokenizer(0, in, lex);
262
        Token                t = tokenizer.getToken();
263

264
        while(t.type() != LexemeType::Empty) {
265
            command.push_back(t);
266
            t = tokenizer.getToken();
267
        }
268

269
        if (command.empty() || command[0].type() != LexemeType::Id) {
270
            std::cout << "*** Wrong command" << std::endl;
271
            continue;
272
        }
273

274
        if (command[0].lexeme() == u"o")
275
            performOpenCommand(client, command);
276
        else if (command[0].lexeme() == u"c")
277
            performCloseCommand(client, command);
278
        else if (command[0].lexeme() == u"u")
279
            performChangeCommand(client, command);
280
        else if (command[0].lexeme() == u"h")
281
            performHoverCommand(client, command);
282
        else if (command[0].lexeme() == u"go")
283
            performDefinitionCommand(client, command);
284
        else if (command[0].lexeme() == u"w")
285
            performWaitCommand(client, command);
286
        // Запускается автоматически при получении диагностики
287
        // else if (command[0].lexeme() == u"s")
288
        //     performDocSymbolsCommand(client, command);
289
        // else if (command[0].lexeme() == u"t")
290
        //     performSemTokensCommand(client, command);
291
        else if (command[0].lexeme() == u"sf")
292
            performSegmentationFaultCommand(client, command);
293
        else {
294
            std::cout << "*** Command don't recognized" << std::endl;
295
            continue;
296
        }
297

298
        if (!client.running()) {
299
            std::cout << "*** Server don't running" << std::endl;
300
            return 1;
301
        }
302
    }
303

304
    // std::this_thread::sleep_for(std::chrono::milliseconds(1000));
305
    // client.done(1000);
306
    std::this_thread::sleep_for(std::chrono::milliseconds(5000));
307

308
    if (client.ok()) {
309
        std::cout << "Done" << std::endl;
310
        return 0;
311
    }
312
    else {
313
        std::cout << "Something is wrong" << std::endl;
314
        return 1;
315
    }
316
}
317

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

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

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

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