1// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5#include "protocol.h"
6#include "newprotocol.h"
7#include "common/util/processutil.h"
8
9#include <QVariantMap>
10#include <QJsonDocument>
11#include <QJsonObject>
12#include <QJsonArray>
13#include <QCoreApplication>
14#include <QQueue>
15#include <QUrl>
16#include <QDir>
17#include <QDebug>
18#include <QFile>
19#include <QFileInfo>
20
21namespace lsp {
22
23const QString C_CPP{"C/C++"};
24const QString JAVA{"Java"};
25const QString PYTHON{"Python"};
26const QString JS{"JS"};
27const QString K_ID {"id"};
28const QString K_JSON_RPC {"jsonrpc"};
29const QString K_METHOD {"method"};
30const QString K_RESULT {"result"};
31const QString K_PARAMS {"params"};
32const QString K_CAPABILITIES {"capabilities"};
33const QString K_TEXTDOCUMENT {"textDocument"};
34const QString K_DOCUMENTSYMBOL {"documentSymbol"};
35const QString K_HIERARCHICALDOCUMENTSYMBOLSUPPORT {"hierarchicalDocumentSymbolSupport"};
36const QString K_PUBLISHDIAGNOSTICS {"publishDiagnostics"};
37const QString K_RELATEDINFOMATION {"relatedInformation"};
38const QString K_INITIALIZATIONOPTIONS {"initializationOptions"};
39const QString K_PROCESSID {"processId"};
40const QString K_ROOTPATH {"rootPath"};
41const QString K_ROOTURI {"rootUri"};
42const QString K_URI {"uri"}; // value QString from file url
43const QString K_VERSION {"version"}; // value int
44const QString K_LANGUAGEID {"languageId"};
45const QString K_TEXT {"text"};
46const QString K_CONTAINERNAME {"containerName"};
47const QString K_KIND {"kind"};
48const QString K_LOCATION {"location"};
49const QString K_POSITION {"position"};
50const QString K_DATA{"data"};
51const QString K_NewName{"newName"};
52const QString K_NewText{"newText"};
53
54const QString H_CONTENT_LENGTH {"Content-Length"};
55const QString V_2_0 {"2.0"};
56const QString V_INITIALIZE {"initialize"}; //has request result
57const QString V_SHUTDOWN {"shutdown"}; //has request result
58const QString V_EXIT{"exit"}; //has request result
59const QString V_TEXTDOCUMENT_DIDOPEN {"textDocument/didOpen"}; //no request result
60const QString V_TEXTDOCUMENT_PUBLISHDIAGNOSTICS {"textDocument/publishDiagnostics"}; //server call
61const QString V_TEXTDOCUMENT_DIDCHANGE {"textDocument/didChange"}; //no request result, json error
62const QString V_TEXTDOCUMENT_DOCUMENTSYMBOL {"textDocument/documentSymbol"}; // has request result
63const QString V_TEXTDOCUMENT_HOVER {"textDocument/hover"}; // has request result
64const QString V_TEXTDOCUMENT_RENAME {"textDocument/rename"}; // has request result
65const QString V_TEXTDOCUMENT_DEFINITION {"textDocument/definition"};
66const QString V_TEXTDOCUMENT_DIDCLOSE {"textDocument/didClose"};
67const QString V_TEXTDOCUMENT_COMPLETION {"textDocument/completion"};
68const QString V_TEXTDOCUMENT_SIGNATUREHELP {"textDocument/signatureHelp"};
69const QString V_TEXTDOCUMENT_REFERENCES {"textDocument/references"};
70const QString V_TEXTDOCUMENT_DOCUMENTHIGHLIGHT {"textDocument/documentHighlight"};
71const QString V_TEXTDOCUMENT_SEMANTICTOKENS {"textDocument/semanticTokens"};
72const QString V_TEXTDOCUMENT_SEMANTICTOKENS_FULL{"textDocument/semanticTokens/full"};
73const QString K_WORKSPACEFOLDERS {"workspaceFolders"};
74
75const QString K_CONTENTCHANGES {"contentChanges"};
76const QString K_DIAGNOSTICS {"diagnostics"};
77const QString K_RANGE {"range"};
78const QString K_MESSAGE {"message"};
79const QString K_SEVERITY {"severity"};
80const QString K_END {"end"};
81const QString K_START {"start"};
82const QString K_CHARACTER {"character"};
83const QString K_LINE {"line"};
84const QString K_CONTEXT {"context"};
85const QString K_INCLUDEDECLARATION {"includeDeclaration"};
86
87const QString K_ERROR {"error"};
88const QString K_CODE {"code"};
89
90QList<int> fromTokenModifiers(int modifiers)
91{
92 QList<int> ret;
93 int temp = modifiers;
94 ret.push_front((int)(temp %10));
95 while (temp / 10 >= 1) {
96 temp = temp / 10;
97 ret.push_front((int)(temp %10));
98 }
99
100 return ret;
101}
102
103QJsonArray tokenTypes()
104{
105 return {
106 "namespace",
107 "type",
108 "class",
109 "enum",
110 "interface",
111 "struct",
112 "typeParameter",
113 "parameter",
114 "variable",
115 "property",
116 "enumMember",
117 "event",
118 "function",
119 "method",
120 "macro",
121 "keyword",
122 "modifier",
123 "comment",
124 "string",
125 "number",
126 "regexp",
127 "operator"
128 };
129}
130
131QJsonArray tokenModifiers()
132{
133 return {
134 "declaration",
135 "definition",
136 "readonly",
137 "static",
138 "deprecated",
139 "abstract",
140 "async",
141 "modification",
142 "documentation",
143 "defaultLibrary"
144 };
145}
146
147QJsonObject workspace()
148{
149 QJsonObject didChangeConfiguration {
150 { "dynamicRegistration", true }
151 };
152 QJsonObject codeLens {
153 { "refreshSupport", true }
154 };
155 QJsonObject didChangeWatchedFiles {
156 { "dynamicRegistration", true}
157 };
158 QJsonObject executeCommand{
159 { "dynamicRegistration", true}
160 };
161 QJsonObject fileOperations {
162 { "didCreate", true},
163 { "didDelete", true},
164 { "didRename", true},
165 { "dynamicRegistration", true},
166 { "willCreate", true},
167 { "willDelete", true},
168 { "willRename", true}
169 };
170 QJsonObject semanticTokens{
171 { "refreshSupport", true }
172 };
173
174 QJsonArray symbolKind_valueSet { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26 };
175 QJsonObject symbolKind{ { "valueSet", symbolKind_valueSet } };
176 QJsonArray tagSupport_valueSet{1};
177 QJsonObject tagSupport{ { "valueSet", tagSupport_valueSet } };
178 QJsonObject symbol{
179 { "dynamicRegistration", true},
180 { "symbolKind", symbolKind },
181 { "tagSupport", tagSupport }
182 };
183
184 QJsonArray resourceOperations{
185 { "create", "rename", "delete" }
186 };
187
188 QJsonObject changeAnnotationSupport{
189 { "groupsOnLabel", true }
190 };
191 QJsonObject workspaceEdit{
192 { "changeAnnotationSupport",changeAnnotationSupport },
193 { "documentChanges", true },
194 { "failureHandling", "textOnlyTransactional" },
195 { "normalizesLineEndings", true },
196 { "resourceOperations", resourceOperations}
197 };
198
199 QJsonObject workspace {
200 { "applyEdit", true },
201 { "codeLens", codeLens },
202 { "configuration", true },
203 { "didChangeConfiguration", didChangeConfiguration },
204 { "didChangeWatchedFiles", didChangeWatchedFiles },
205 { "executeCommand", executeCommand },
206 { "fileOperations", fileOperations },
207 { "semanticTokens", semanticTokens },
208 { "symbol",symbol },
209 { "workspaceEdit", workspaceEdit },
210 { "workspaceFolders", true }
211 };
212
213 return workspace;
214}
215
216QJsonObject initialize(const QString &workspaceFolder, const QString &language, const QString &compile)
217{
218 QJsonObject params;
219 if (language == C_CPP) {
220 QJsonObject capabilitiesSemanticTokens{{
221 {"dynamicRegistration", true},
222 {"formats", QJsonArray{"relative"}},
223 {"multilineTokenSupport", false},
224 {"overlappingTokenSupport", false},
225 {"requests", QJsonArray{"full",QJsonObject{{"delta", true}},QJsonObject{{"range", true}}}},
226 {"tokenModifiers", tokenModifiers()},
227 {"tokenTypes", tokenTypes()}}};
228
229 QJsonObject capabilities {
230 {
231 K_TEXTDOCUMENT, QJsonObject {
232 {"documentLink", QJsonObject{{"dynamicRegistration", true}}},
233 {"documentHighlight", QJsonObject{{"dynamicRegistration", true}}},
234 {K_DOCUMENTSYMBOL, QJsonObject{{K_HIERARCHICALDOCUMENTSYMBOLSUPPORT, true}},},
235 {K_PUBLISHDIAGNOSTICS, QJsonObject{{K_RELATEDINFOMATION, true}}},
236 {"definition", QJsonObject{{{"dynamicRegistration", true},{"linkSupport", true}}}},
237 {"colorProvider", QJsonObject{{"dynamicRegistration", true}}},
238 {"declaration", QJsonObject{{"dynamicRegistration", true},{"linkSupport", true}}},
239 {"semanticHighlightingCapabilities", QJsonObject{{"semanticHighlighting", true}}},
240 {"semanticTokens", capabilitiesSemanticTokens}
241 }
242 },{
243 "workspace", workspace()
244 },{
245 "foldingRangeProvider", true,
246 }
247 };
248
249 QJsonObject highlight {
250 {"largeFileSize", 2097152},
251 {"lsRanges", false},
252 {"blacklist", QJsonArray()},
253 {"whitelist", QJsonArray()}
254 };
255
256 QJsonObject client{
257 {"diagnosticsRelatedInformation", true},
258 {"hierarchicalDocumentSymbolSupport", true},
259 {"linkSupport",true},
260 {"snippetSupport",true},
261 };
262
263 QJsonObject workspace {
264 { "name", QFileInfo(workspaceFolder).fileName() },
265 { K_URI, QUrl::fromLocalFile(workspaceFolder).toString() }
266 };
267
268 QJsonArray workspaceFolders{workspace};
269
270 QJsonObject initializationOptions {
271 {"compilationDatabasePath", compile}
272 };
273
274 QJsonObject params {
275 { K_PROCESSID, QCoreApplication::applicationPid() },
276 { K_ROOTPATH, workspace },
277 { K_ROOTURI, workspace },
278 { K_CAPABILITIES, capabilities },
279 { "highlight", highlight },
280 { "client", client },
281 { "initializationOptions", initializationOptions},
282 { "workspaceFolders", workspaceFolders },
283 };
284
285 return params;
286
287 } else if (language == JAVA || language == PYTHON || language == JS) {
288
289 using namespace newlsp;
290
291 std::string workspaceFolderUriStr = QUrl::fromLocalFile(workspaceFolder).toString().toStdString();
292 std::string workspaceNameStr = QFileInfo(workspaceFolder).fileName().toStdString();
293
294 InitializeParams params;
295
296 /* processId */
297 params.processId = QCoreApplication::applicationPid();
298
299 /* rootUri */
300 params.rootUri = workspaceFolderUriStr;
301
302 /* rootPath */
303 params.rootPath = workspaceFolder.toStdString();
304
305 /* capabilities
306 * std::optional<Workspace> workspace{};
307 * std::optional<TextDocumentClientCapabilities> textDocument{};
308 * std::optional<NotebookDocumentClientCapabilities> notebookDocument{};
309 * std::optional<Window> window{};
310 * std::optional<General> general{};
311 */
312 {
313 /* workspace */
314 {
315 params.capabilities.workspace = newlsp::Workspace{};
316 params.capabilities.workspace->applyEdit = true;
317 /* WorkspaceEditClientCapabilities */
318 params.capabilities.workspace->workspaceEdit = newlsp::WorkspaceEditClientCapabilities{};
319 params.capabilities.workspace->workspaceEdit->documentChanges = true;
320 params.capabilities.workspace->workspaceEdit->resourceOperations = newlsp::Enum::ResourceOperationKind::toStdVector();
321 params.capabilities.workspace->workspaceEdit->failureHandling = newlsp::Enum::FailureHandlingKind::get()->TextOnlyTransactional;
322 params.capabilities.workspace->workspaceEdit->normalizesLineEndings = true;
323 params.capabilities.workspace->workspaceEdit->changeAnnotationSupport = ChangeAnotationSupport{};
324 params.capabilities.workspace->workspaceEdit->changeAnnotationSupport->groupsOnLabel = true;
325
326 /* DidChangeConfigurationClientCapabilities */
327 params.capabilities.workspace->didChangeConfiguration = DidChangeConfigurationClientCapabilities{};
328 params.capabilities.workspace->didChangeConfiguration->dynamicRegistration = true;
329
330 /* DidChangeWatchedFilesClientCapabilities */
331 params.capabilities.workspace->didChangeWatchedFiles = DidChangeWatchedFilesClientCapabilities{};
332 params.capabilities.workspace->didChangeWatchedFiles->dynamicRegistration = true;
333 // no setting from vscode
334 // params.capabilities.workspace->didChangeWatchedFiles->relativePatternSupport = true;
335
336 /* WorkspaceSymbolClientCapabilities*/
337 params.capabilities.workspace->symbol = WorkspaceSymbolClientCapabilities{};
338 params.capabilities.workspace->symbol->dynamicRegistration = true;
339 params.capabilities.workspace->symbol->symbolKind = SymbolKind{};
340 params.capabilities.workspace->symbol->symbolKind->valueSet = newlsp::Enum::SymbolKind::toStdVector();
341 params.capabilities.workspace->symbol->tagSupport = WorkspaceSymbolClientCapabilities::TagSupport{};
342 params.capabilities.workspace->symbol->tagSupport->valueSet = newlsp::Enum::SymbolTag::toStdVector();
343 // no setting from vscode
344 // params.capabilities.workspace->symbol->resolveSupport = {};
345
346 /* ExecuteCommandClientCapabilities */
347 params.capabilities.workspace->executeCommand = ExecuteCommandClientCapabilities{};
348 params.capabilities.workspace->executeCommand->dynamicRegistration = true;
349
350 /* workspaceFolders */
351 params.capabilities.workspace->workspaceFolders = true;
352
353 /* configuration */
354 params.capabilities.workspace->configuration = true;
355
356 /* SemanticTokensWorkspaceClientCapabilities */
357 params.capabilities.workspace->semanticTokens = SemanticTokensWorkspaceClientCapabilities{};
358 params.capabilities.workspace->semanticTokens->refreshSupport = true;
359
360 /* CodeLensWorkspaceClientCapabilities */
361 params.capabilities.workspace->codeLens = CodeLensWorkspaceClientCapabilities{};
362 params.capabilities.workspace->codeLens->refreshSupport = true;
363
364 /* FileOperations */
365 params.capabilities.workspace->fileOperations = FileOperations{};
366 params.capabilities.workspace->fileOperations->dynamicRegistration = true;
367 params.capabilities.workspace->fileOperations->didCreate = true;
368 params.capabilities.workspace->fileOperations->willCreate = true;
369 params.capabilities.workspace->fileOperations->didRename = true;
370 params.capabilities.workspace->fileOperations->willRename = true;
371 params.capabilities.workspace->fileOperations->didDelete = true;
372 params.capabilities.workspace->fileOperations->willDelete = true;
373
374 /* InlineValueWorkspaceClientCapabilities */
375 //no setting from vscode
376 // params.capabilities.workspace->inlineValue = InlineValueWorkspaceClientCapabilities{};
377 // params.capabilities.workspace->inlineValue->refreshSupport = true;
378
379 /* InlayHintWorkspaceClientCapabilities */
380 // no setting from vscode
381 // params.capabilities.workspace->inlayHint = InlayHintWorkspaceClientCapabilities{};
382 // params.capabilities.workspace->inlayHint->refreshSupport = true;
383
384 /* DiagnosticWorkspaceClientCapabilities */
385 // no setting from vscode
386 // params.capabilities.workspace->diagnostics = DiagnosticWorkspaceClientCapabilities{};
387 // params.capabilities.workspace->diagnostics->refreshSupport = true;
388 }
389 /* textDocument */
390 {
391 params.capabilities.textDocument = TextDocumentClientCapabilities{};
392
393 /* TextDocumentSyncClientCapabilities */
394 params.capabilities.textDocument->synchronization = TextDocumentSyncClientCapabilities{};
395 params.capabilities.textDocument->synchronization->dynamicRegistration = true;
396 params.capabilities.textDocument->synchronization->willSave = true;
397 params.capabilities.textDocument->synchronization->willSaveWaitUntil = true;
398 params.capabilities.textDocument->synchronization->didSave = true;
399
400 /* CompletionClientCapabilities */
401 params.capabilities.textDocument->completion = CompletionClientCapabilities{};
402 params.capabilities.textDocument->completion->dynamicRegistration = true;
403 params.capabilities.textDocument->completion->contextSupport = true;
404
405 params.capabilities.textDocument->completion->completionItem = CompletionClientCapabilities::CompletionItem{};
406 params.capabilities.textDocument->completion->completionItem->snippetSupport = true;
407 params.capabilities.textDocument->completion->completionItem->commitCharactersSupport = true;
408 params.capabilities.textDocument->completion->completionItem->documentationFormat = newlsp::Enum::MarkupKind::toStdVector();
409 params.capabilities.textDocument->completion->completionItem->deprecatedSupport = true;
410 params.capabilities.textDocument->completion->completionItem->preselectSupport = true;
411 params.capabilities.textDocument->completion->completionItem->tagSupport
412 = CompletionClientCapabilities::CompletionItem::TagSupport{};
413 params.capabilities.textDocument->completion->completionItem->tagSupport->valueSet
414 = newlsp::Enum::CompletionItemTag::toStdVector();
415 params.capabilities.textDocument->completion->completionItem->insertReplaceSupport = true;
416 params.capabilities.textDocument->completion->completionItem->resolveSupport = ResolveSupport{};
417 params.capabilities.textDocument->completion->completionItem->resolveSupport->properties = {
418 "documentation",
419 "detail",
420 "additionalTextEdits"
421 }; // from vs code
422 params.capabilities.textDocument->completion->completionItem->insertTextModeSupport
423 = CompletionClientCapabilities::CompletionItem::InsertTextModeSupport{};
424 params.capabilities.textDocument->completion->completionItem->insertTextModeSupport->valueSet
425 = newlsp::Enum::InsertTextMode::toStdVector();
426 params.capabilities.textDocument->completion->completionItem->labelDetailsSupport = true;
427
428 /* insertTextMode: 2 */
429 params.capabilities.textDocument->completion->insertTextMode
430 = newlsp::Enum::InsertTextMode::get()->adjustIndentation; // from vscode
431
432 /* completionItemKind */
433 params.capabilities.textDocument->completion->completionItemKind
434 = CompletionClientCapabilities::CompletionItemKind{};
435 params.capabilities.textDocument->completion->completionItemKind->valueSet
436 = newlsp::Enum::CompletionItemKind::toStdVector();
437
438 /* itemDefaults */ // no setting from vscode
439 // params.capabilities.textDocument->completion->itemDefaults = {std::nullopt};
440
441 /* contextSupport */
442 params.capabilities.textDocument->completion->contextSupport = true;
443
444 /* HoverClientCapabilities */
445 params.capabilities.textDocument->hover = HoverClientCapabilities{};
446 params.capabilities.textDocument->hover->dynamicRegistration = true;
447 params.capabilities.textDocument->hover->contentFormat = newlsp::Enum::MarkupKind::toStdVector();
448
449 /* SignatureHelpClientCapabilities */
450 params.capabilities.textDocument->signatureHelp = SignatureHelpClientCapabilities{};
451 params.capabilities.textDocument->signatureHelp->dynamicRegistration = true;
452 params.capabilities.textDocument->signatureHelp->signatureInformation = SignatureHelpClientCapabilities::SignatureInformation{};
453 params.capabilities.textDocument->signatureHelp->signatureInformation->documentationFormat = newlsp::Enum::MarkupKind::toStdVector();
454 params.capabilities.textDocument->signatureHelp->signatureInformation->parameterInformation
455 = SignatureHelpClientCapabilities::SignatureInformation::ParameterInformation{};
456 params.capabilities.textDocument->signatureHelp->signatureInformation->parameterInformation->labelOffsetSupport = true;
457 params.capabilities.textDocument->signatureHelp->signatureInformation->activeParameterSupport = true;
458 params.capabilities.textDocument->signatureHelp->contextSupport = true;
459
460 /* DeclarationClientCapabilities */
461 params.capabilities.textDocument->declaration = DeclarationClientCapabilities{};
462 params.capabilities.textDocument->declaration->dynamicRegistration = true;
463 params.capabilities.textDocument->declaration->linkSupport = true;
464
465 /* DefinitionClientCapabilities */
466 params.capabilities.textDocument->definition = DefinitionClientCapabilities{};
467 params.capabilities.textDocument->definition->dynamicRegistration = true;
468 params.capabilities.textDocument->definition->linkSupport = true;
469
470 /* TypeDefinitionClientCapabilities */
471 params.capabilities.textDocument->typeDefinition = TypeDefinitionClientCapabilities{};
472 params.capabilities.textDocument->typeDefinition->dynamicRegistration = true;
473 params.capabilities.textDocument->typeDefinition->linkSupport = true;
474
475 /* ImplementationClientCapabilities */
476 params.capabilities.textDocument->implementation = ImplementationClientCapabilities{};
477 params.capabilities.textDocument->implementation->dynamicRegistration = true;
478 params.capabilities.textDocument->implementation->linkSupport = true;
479
480 /* ReferenceClientCapabilities */
481 params.capabilities.textDocument->references = ReferenceClientCapabilities{};
482 params.capabilities.textDocument->references->dynamicRegistration = true;
483
484 /* DocumentHighlightClientCapabilities */
485 params.capabilities.textDocument->documentHighlight = DocumentHighlightClientCapabilities{};
486 params.capabilities.textDocument->documentHighlight->dynamicRegistration = true;
487
488 /* DocumentSymbolClientCapabilities */
489 params.capabilities.textDocument->documentSymbol = DocumentSymbolClientCapabilities{};
490 params.capabilities.textDocument->documentSymbol->dynamicRegistration = true;
491 params.capabilities.textDocument->documentSymbol->symbolKind = SymbolKind{};
492 params.capabilities.textDocument->documentSymbol->symbolKind->valueSet = newlsp::Enum::SymbolKind::toStdVector();
493 params.capabilities.textDocument->documentSymbol->hierarchicalDocumentSymbolSupport = true;
494 params.capabilities.textDocument->documentSymbol->tagSupport = DocumentSymbolClientCapabilities::TagSupport{};
495 params.capabilities.textDocument->documentSymbol->tagSupport->valueSet = newlsp::Enum::SymbolTag::toStdVector();
496 params.capabilities.textDocument->documentSymbol->labelSupport = true;
497
498 /* CodeActionClientCapabilities */ //func
499 params.capabilities.textDocument->codeAction = CodeActionClientCapabilities{};
500 params.capabilities.textDocument->codeAction->dynamicRegistration = true;
501 params.capabilities.textDocument->codeAction->isPreferredSupport = true;
502 params.capabilities.textDocument->codeAction->disabledSupport = true;
503 params.capabilities.textDocument->codeAction->dataSupport = true;
504 params.capabilities.textDocument->codeAction->resolveSupport = ResolveSupport{};
505 params.capabilities.textDocument->codeAction->resolveSupport->properties = {newlsp::Enum::Properties::get()->edit};
506 params.capabilities.textDocument->codeAction->codeActionLiteralSupport = CodeActionLiteralSupport{};
507 params.capabilities.textDocument->codeAction->codeActionLiteralSupport->codeActionKind = CodeActionKind{};
508 params.capabilities.textDocument->codeAction->codeActionLiteralSupport->codeActionKind.valueSet
509 = newlsp::Enum::CodeActionKind::toStdVector();
510 params.capabilities.textDocument->codeAction->honorsChangeAnnotations = false;
511
512 /* CodeLensClientCapabilities */
513 params.capabilities.textDocument->codeLens = CodeLensClientCapabilities{};
514 params.capabilities.textDocument->codeLens->dynamicRegistration = true;
515
516 /* DocumentLinkClientCapabilities */
517 params.capabilities.textDocument->documentLink = DocumentLinkClientCapabilities {};
518 params.capabilities.textDocument->documentLink->dynamicRegistration = true;
519 params.capabilities.textDocument->documentLink->tooltipSupport = true;
520
521 /* DocumentColorClientCapabilities */
522 params.capabilities.textDocument->colorProvider = DocumentColorClientCapabilities{};
523 params.capabilities.textDocument->colorProvider->dynamicRegistration = true;
524
525 /* DocumentFormattingClientCapabilities */
526 params.capabilities.textDocument->formatting = DocumentFormattingClientCapabilities{};
527 params.capabilities.textDocument->formatting->dynamicRegistration = true;
528
529 /* DocumentFormattingClientCapabilities */
530 params.capabilities.textDocument->rangeFormatting = DocumentRangeFormattingClientCapabilities{};
531 params.capabilities.textDocument->rangeFormatting->dynamicRegistration = true;
532
533 /* DocumentRangeFormattingClientCapabilities */
534 params.capabilities.textDocument->onTypeFormatting = DocumentOnTypeFormattingClientCapabilities{};
535 params.capabilities.textDocument->onTypeFormatting->dynamicRegistration = true;
536
537 /* RenameClientCapabilities */
538 params.capabilities.textDocument->rename = RenameClientCapabilities{};
539 params.capabilities.textDocument->rename->dynamicRegistration = true;
540 params.capabilities.textDocument->rename->prepareSupport = true;
541 params.capabilities.textDocument->rename->prepareSupportDefaultBehavior
542 = newlsp::Enum::PrepareSupportDefaultBehavior::get()->Identifier;
543 params.capabilities.textDocument->rename->honorsChangeAnnotations = true;
544
545 /* PublishDiagnosticsClientCapabilities */
546 params.capabilities.textDocument->publishDiagnostics = PublishDiagnosticsClientCapabilities{};
547 params.capabilities.textDocument->publishDiagnostics->relatedInformation = true;
548 params.capabilities.textDocument->publishDiagnostics->tagSupport
549 = PublishDiagnosticsClientCapabilities::TagSupport{};
550 params.capabilities.textDocument->publishDiagnostics->tagSupport->valueSet = newlsp::Enum::DiagnosticTag::toStdVector();
551 params.capabilities.textDocument->publishDiagnostics->versionSupport = false;
552 params.capabilities.textDocument->publishDiagnostics->codeDescriptionSupport = true;
553 params.capabilities.textDocument->publishDiagnostics->dataSupport = true;
554
555 /* FoldingRangeClientCapabilities */
556 params.capabilities.textDocument->foldingRange = FoldingRangeClientCapabilities{};
557 params.capabilities.textDocument->foldingRange->dynamicRegistration = true;
558 params.capabilities.textDocument->foldingRange->rangeLimit = 5000; // vscode 5000
559 params.capabilities.textDocument->foldingRange->lineFoldingOnly = true;
560 // no setting from vscode
561 // params.capabilities.textDocument->foldingRange->foldingRangeKind = FoldingRangeKind{};
562 // params.capabilities.textDocument->foldingRange->foldingRangeKind->valueSet = {newlsp::Enum::FoldingRangeKind::toStdVector()};
563 // params.capabilities.textDocument->foldingRange->foldingRange = FoldingRange{};
564 // params.capabilities.textDocument->foldingRange->foldingRange->collapsedText = true;
565
566 /* SelectionRangeClientCapabilities */
567 params.capabilities.textDocument->selectionRange = SelectionRangeClientCapabilities{};
568 params.capabilities.textDocument->selectionRange->dynamicRegistration = true;
569
570 /* LinkedEditingRangeClientCapabilities */
571 params.capabilities.textDocument->linkedEditingRange = LinkedEditingRangeClientCapabilities{};
572 params.capabilities.textDocument->linkedEditingRange->dynamicRegistration = true;
573
574 /* CallHierarchyClientCapabilities */
575 params.capabilities.textDocument->callHierarchy = CallHierarchyClientCapabilities{};
576 params.capabilities.textDocument->callHierarchy->dynamicRegistration = true;
577
578 /* SemanticTokensClientCapabilities */
579 params.capabilities.textDocument->semanticTokens = SemanticTokensClientCapabilities{};
580 params.capabilities.textDocument->semanticTokens->dynamicRegistration = true;
581 params.capabilities.textDocument->semanticTokens->tokenTypes = newlsp::Enum::SemanticTokenTypes::toStdVector();
582 params.capabilities.textDocument->semanticTokens->tokenModifiers = newlsp::Enum::SemanticTokenModifiers::toStdVector();
583 params.capabilities.textDocument->semanticTokens->formats = newlsp::Enum::TokenFormat::toStdVector();
584 params.capabilities.textDocument->semanticTokens->requests = SemanticTokensClientCapabilities::Requests{};
585 params.capabilities.textDocument->semanticTokens->requests.full = SemanticTokensClientCapabilities::Requests::Full{};
586 params.capabilities.textDocument->semanticTokens->requests.full->delta = true;
587 params.capabilities.textDocument->semanticTokens->requests.range = std::optional<std::any>(true);
588 params.capabilities.textDocument->semanticTokens->multilineTokenSupport = false; // from vscode
589 params.capabilities.textDocument->semanticTokens->overlappingTokenSupport = false; // from vscode
590 // no setting from vscode
591 // params.capabilities.textDocument->semanticTokens->serverCancelSupport = true;
592 // params.capabilities.textDocument->semanticTokens->augmentsSyntaxTokens = true;
593
594 /* MonikerClientCapabilities */ // no setting from vscode
595 // MonikerClientCapabilities monikerClientCapabilities{};
596 // monikerClientCapabilities.dynamicRegistration = true;
597 // params.capabilities.textDocument->moniker = {monikerClientCapabilities};
598
599 /* TypeHierarchyClientCapabilities */ // no setting from vscode
600 // TypeHierarchyClientCapabilities typeHierarchyClientCapabilities{};
601 // typeHierarchyClientCapabilities.dynamicRegistration = true;
602 // params.capabilities.textDocument->typeHierarchy = {typeHierarchyClientCapabilities};
603
604 /* InlineValueClientCapabilities */ // no setting from vscode
605 // InlineValueClientCapabilities inlineValueClientCapabilities{};
606 // inlineValueClientCapabilities.dynamicRegistration = true;
607 // params.capabilities.textDocument->inlineValue = {inlineValueClientCapabilities};
608
609 /* InlayHintClientCapabilities */ // no setting from vscode
610 // params.capabilities.textDocument->inlayHint = InlayHintClientCapabilities{};
611 // params.capabilities.textDocument->inlayHint->dynamicRegistration = true;
612 // params.capabilities.textDocument->inlayHint->resolveSupport = ResolveSupport{};
613 // params.capabilities.textDocument->inlayHint->resolveSupport->properties
614 // = {newlsp::Enum::Properties::get()->label_location};
615
616 /* DiagnosticClientCapabilities */ // no setting from vscode
617 // DiagnosticClientCapabilities diagnosticClientCapabilities{};
618 // diagnosticClientCapabilities.dynamicRegistration = true;
619 // diagnosticClientCapabilities.relatedDocumentSupport = true;
620 // params.capabilities.textDocument->diagnostic = {diagnosticClientCapabilities};
621 }
622 /* notebookDocument */
623 {
624 // no setting from vscode
625 // params.capabilities.notebookDocument = NotebookDocumentClientCapabilities{};
626 // params.capabilities.notebookDocument->synchronization.dynamicRegistration = true;
627 // params.capabilities.notebookDocument->synchronization.executionSummarySupport = true;
628 }
629 /* window */
630 {
631 params.capabilities.window = Window{};
632 params.capabilities.window->workDoneProgress = true;
633 params.capabilities.window->showMessage = ShowMessageRequestClientCapabilities{};
634 params.capabilities.window->showMessage->messageActionItem = MessageActionItem{};
635 params.capabilities.window->showMessage->messageActionItem->additionalPropertiesSupport = true;
636 params.capabilities.window->showDocument = ShowDocumentClientCapabilities{};
637 params.capabilities.window->showDocument->support = true;
638 }
639 /* general */
640 {
641 params.capabilities.general = General{};
642 params.capabilities.general->staleRequestSupport = StaleRequestSupport{};
643 params.capabilities.general->staleRequestSupport->cancel = true;
644 params.capabilities.general->staleRequestSupport->retryOnContentModified = {
645 "textDocument/semanticTokens/full",
646 "textDocument/semanticTokens/range",
647 "textDocument/semanticTokens/full/delta"
648 };
649 params.capabilities.general->regularExpressions = RegularExpressionsClientCapabilities{};
650 params.capabilities.general->regularExpressions->engine = "ECMAScript";
651 params.capabilities.general->regularExpressions->version = "ES2020";
652 params.capabilities.general->markdown = MarkdownClientCapabilities{};
653 params.capabilities.general->markdown->parser = "marked";
654 params.capabilities.general->markdown->version = "1.1.0";
655 }
656 }
657
658 /* trace */
659 {
660 params.trace = newlsp::Enum::TraceValue::get()->Verbose;
661 }
662
663 /* workspaceFolders */
664 {
665 std::vector<WorkspaceFolder> workspaceFolders{};
666 WorkspaceFolder folderParams;
667 folderParams.uri = workspaceFolderUriStr;
668 folderParams.name = workspaceNameStr;
669 workspaceFolders.push_back(folderParams);
670 params.workspaceFolders = {workspaceFolders};
671 }
672
673 QJsonParseError err;
674 auto jsonDoc = QJsonDocument::fromJson(QByteArray::fromStdString(toJsonValueStr(params)), &err);
675 if (err.error != QJsonParseError::NoError)
676 qCritical() << err.errorString();
677 return jsonDoc.object();
678 }
679 return {};
680}
681
682QJsonObject didOpen(const QString &filePath)
683{
684 QFile file(filePath);
685 QString text;
686 if (!file.open(QFile::ReadOnly)) {
687 qCritical()<< "Failed, open file: "
688 << filePath <<file.errorString();
689 }
690 text = file.readAll();
691 file.close();
692
693 QJsonObject textDocument{
694 { K_URI, QUrl::fromLocalFile(filePath).toString() },
695 { K_LANGUAGEID, "cpp" },
696 { K_VERSION, 1 },
697 { K_TEXT, text }
698 };
699
700 QJsonObject params{
701 { K_TEXTDOCUMENT, textDocument }
702 };
703
704 return params;
705}
706
707// full mode
708QJsonObject didChange(const QString &filePath, const QByteArray &text, int version)
709{
710 QJsonObject changeEvent
711 {
712 { K_TEXT, QString::fromUtf8(text)}
713 };
714
715 QJsonArray contentChanges
716 {
717 changeEvent
718 };
719
720 QJsonObject textDocument
721 {
722 { K_URI, QUrl::fromLocalFile(filePath).toString() },
723 { K_VERSION, version }
724 };
725
726 QJsonObject params {
727 { K_TEXTDOCUMENT, textDocument },
728 { "contentChanges", contentChanges }
729 };
730
731 return params;
732}
733
734QJsonObject didClose(const QString &filePath)
735{
736 QJsonObject textDocument {
737 { K_URI, QUrl::fromLocalFile(filePath).toString() }
738 };
739
740 QJsonObject params{
741 { K_TEXTDOCUMENT, textDocument},
742 };
743
744 return params;
745}
746
747QJsonObject hover(const QString &filePath, const Position &pos)
748{
749 QJsonObject textDocument {
750 { K_URI, QUrl::fromLocalFile(filePath).toString() },
751 };
752
753 QJsonObject position {
754 { K_CHARACTER, pos.character },
755 { K_LINE, pos.line }
756 };
757
758 QJsonObject params {
759 { K_TEXTDOCUMENT, textDocument},
760 { K_POSITION, position }
761 };
762
763 return params;
764}
765
766QJsonObject definition(const QString &filePath, const Position &pos)
767{
768 QJsonObject textDocument {
769 { K_URI, QUrl::fromLocalFile(filePath).toString() }
770 };
771
772 QJsonObject position {
773 { K_CHARACTER, pos.character },
774 { K_LINE, pos.line }
775 };
776
777 QJsonObject params {
778 { K_TEXTDOCUMENT, textDocument },
779 { K_POSITION, position}
780 };
781
782 return params;
783}
784
785QJsonObject signatureHelp(const QString &filePath, const Position &pos)
786{
787 QJsonObject textDocument {
788 { K_URI, QUrl::fromLocalFile(filePath).toString() }
789 };
790
791 QJsonObject position {
792 { K_CHARACTER, pos.character },
793 { K_LINE, pos.line }
794 };
795
796 QJsonObject params {
797 { K_TEXTDOCUMENT, textDocument },
798 { K_POSITION, position}
799 };
800
801 return params;
802}
803
804QJsonObject references(const QString &filePath, const Position &pos)
805{
806 QJsonObject textDocument {
807 { K_URI, QUrl::fromLocalFile(filePath).toString() }
808 };
809
810 QJsonObject position {
811 { K_CHARACTER, pos.character },
812 { K_LINE, pos.line }
813 };
814
815 QJsonObject context {
816 { K_INCLUDEDECLARATION, true}
817 };
818
819 QJsonObject params {
820 { K_CONTEXT, context},
821 { K_TEXTDOCUMENT, textDocument },
822 { K_POSITION, position}
823 };
824
825 return params;
826}
827
828QJsonObject documentHighlight(const QString &filePath, const Position &pos)
829{
830 QJsonObject textDocument {
831 { K_URI, QUrl::fromLocalFile(filePath).toString() }
832 };
833
834 QJsonObject position {
835 { K_CHARACTER, pos.character },
836 { K_LINE, pos.line }
837 };
838
839 QJsonObject params {
840 { K_TEXTDOCUMENT, textDocument },
841 { K_POSITION, position }
842 };
843
844 return params;
845}
846
847//more see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_semanticTokens
848QJsonObject documentSemanticTokensFull(const QString &filePath)
849{
850 QJsonObject textDocument {
851 { K_URI, QUrl::fromLocalFile(filePath).toString() }
852 };
853
854 QJsonObject params {
855 { K_TEXTDOCUMENT, textDocument }
856 };
857
858 return params;
859}
860
861QJsonObject documentSemanticTokensRange(const QString &filePath)
862{
863 Q_UNUSED(filePath)
864 return {};
865}
866
867QJsonObject documentSemanticTokensDelta(const QString &filePath)
868{
869 Q_UNUSED(filePath)
870 return {};
871}
872
873QJsonObject shutdown()
874{
875 return {};
876}
877
878QJsonObject symbol(const QString &filePath)
879{
880 QJsonObject textDocument {
881 { K_URI, QUrl::fromLocalFile(filePath).toString() }
882 };
883
884 QJsonObject params {
885 { K_TEXTDOCUMENT, textDocument }
886 };
887
888 return params;
889}
890
891QJsonObject rename(const QString &filePath, const Position &pos, const QString &newName)
892{
893 QJsonObject params;
894 params[K_NewName] = newName;
895 params[K_POSITION] = QJsonObject{{K_LINE, pos.line},{K_CHARACTER, pos.character}};
896 params[K_TEXTDOCUMENT] = QJsonObject{{K_URI, QUrl::fromLocalFile(filePath).toString()}} ;
897
898 return params;
899}
900
901QJsonObject completion(const QString &filePath, const Position &pos)
902{
903 QJsonObject textDocument {
904 { K_URI, QUrl::fromLocalFile(filePath).toString() }
905 };
906
907 QJsonObject position {
908 { K_CHARACTER, pos.character },
909 { K_LINE, pos.line }
910 };
911
912 QJsonObject params {
913 { K_TEXTDOCUMENT, textDocument },
914 { K_POSITION, position}
915 };
916
917 return params;
918}
919
920bool isRequestResult(const QJsonObject &object)
921{
922 QStringList keys = object.keys();
923 if (keys.contains(K_ID) && keys.contains(K_RESULT))
924 return true;
925 return false;
926}
927
928bool isRequestError(const QJsonObject &object)
929{
930 if (object.keys().contains(K_ERROR)) {
931 qInfo() << "Failed, Request error";
932 return true;
933 }
934 return false;
935}
936
937QJsonObject exit()
938{
939 return {};
940}
941
942}
943