mirror of https://gitlab.com/cppit/jucipp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
584 lines
14 KiB
584 lines
14 KiB
#include "json.hpp" |
|
#include <boost/filesystem.hpp> |
|
#include <iostream> |
|
#include <sstream> |
|
|
|
#ifdef _WIN32 |
|
#include <fcntl.h> |
|
#include <io.h> |
|
#endif |
|
|
|
int main() { |
|
#ifdef _WIN32 |
|
_setmode(_fileno(stdout), _O_BINARY); |
|
#endif |
|
|
|
auto tests_path = boost::filesystem::canonical(JUCI_TESTS_PATH); |
|
auto file_path = boost::filesystem::canonical(tests_path / "language_protocol_test_files" / "main.rs"); |
|
|
|
std::string line; |
|
try { |
|
// Read initialize and respond |
|
{ |
|
std::getline(std::cin, line); |
|
auto size = std::atoi(line.substr(16).c_str()); |
|
std::getline(std::cin, line); |
|
std::string buffer; |
|
buffer.resize(size); |
|
std::cin.read(&buffer[0], size); |
|
std::stringstream ss(buffer); |
|
JSON object(ss); |
|
if(object.string("method") != "initialize") |
|
return 1; |
|
|
|
std::string result = R"({ |
|
"id": 0, |
|
"jsonrpc": "2.0", |
|
"result": { |
|
"capabilities": { |
|
"callHierarchyProvider": true, |
|
"codeActionProvider": { |
|
"codeActionKinds": [ |
|
"", |
|
"quickfix", |
|
"refactor", |
|
"refactor.extract", |
|
"refactor.inline", |
|
"refactor.rewrite" |
|
], |
|
"resolveProvider": true |
|
}, |
|
"codeLensProvider": { |
|
"resolveProvider": true |
|
}, |
|
"completionProvider": { |
|
"triggerCharacters": [ |
|
":", |
|
".", |
|
"'" |
|
] |
|
}, |
|
"definitionProvider": true, |
|
"documentFormattingProvider": true, |
|
"documentHighlightProvider": true, |
|
"documentOnTypeFormattingProvider": { |
|
"firstTriggerCharacter": "=", |
|
"moreTriggerCharacter": [ |
|
".", |
|
">", |
|
"{" |
|
] |
|
}, |
|
"documentSymbolProvider": true, |
|
"experimental": { |
|
"joinLines": true, |
|
"onEnter": true, |
|
"parentModule": true, |
|
"runnables": { |
|
"kinds": [ |
|
"cargo" |
|
] |
|
}, |
|
"ssr": true, |
|
"workspaceSymbolScopeKindFiltering": true |
|
}, |
|
"foldingRangeProvider": true, |
|
"hoverProvider": true, |
|
"implementationProvider": true, |
|
"referencesProvider": true, |
|
"renameProvider": { |
|
"prepareProvider": true |
|
}, |
|
"selectionRangeProvider": true, |
|
"semanticTokensProvider": { |
|
"full": { |
|
"delta": true |
|
}, |
|
"legend": { |
|
"tokenModifiers": [ |
|
"documentation", |
|
"declaration", |
|
"definition", |
|
"static", |
|
"abstract", |
|
"deprecated", |
|
"readonly", |
|
"constant", |
|
"controlFlow", |
|
"injected", |
|
"mutable", |
|
"consuming", |
|
"async", |
|
"unsafe", |
|
"attribute", |
|
"trait", |
|
"callable", |
|
"intraDocLink" |
|
], |
|
"tokenTypes": [ |
|
"comment", |
|
"keyword", |
|
"string", |
|
"number", |
|
"regexp", |
|
"operator", |
|
"namespace", |
|
"type", |
|
"struct", |
|
"class", |
|
"interface", |
|
"enum", |
|
"enumMember", |
|
"typeParameter", |
|
"function", |
|
"method", |
|
"property", |
|
"macro", |
|
"variable", |
|
"parameter", |
|
"angle", |
|
"arithmetic", |
|
"attribute", |
|
"bitwise", |
|
"boolean", |
|
"brace", |
|
"bracket", |
|
"builtinType", |
|
"characterLiteral", |
|
"colon", |
|
"comma", |
|
"comparison", |
|
"constParameter", |
|
"dot", |
|
"escapeSequence", |
|
"formatSpecifier", |
|
"generic", |
|
"label", |
|
"lifetime", |
|
"logical", |
|
"operator", |
|
"parenthesis", |
|
"punctuation", |
|
"selfKeyword", |
|
"semicolon", |
|
"typeAlias", |
|
"union", |
|
"unresolvedReference" |
|
] |
|
}, |
|
"range": true |
|
}, |
|
"signatureHelpProvider": { |
|
"triggerCharacters": [ |
|
"(", |
|
"," |
|
] |
|
}, |
|
"textDocumentSync": { |
|
"change": 2, |
|
"openClose": true, |
|
"save": {} |
|
}, |
|
"typeDefinitionProvider": true, |
|
"workspace": { |
|
"fileOperations": { |
|
"willRename": { |
|
"filters": [ |
|
{ |
|
"pattern": { |
|
"glob": "**/*.rs", |
|
"matches": "file" |
|
}, |
|
"scheme": "file" |
|
}, |
|
{ |
|
"pattern": { |
|
"glob": "**", |
|
"matches": "folder" |
|
}, |
|
"scheme": "file" |
|
} |
|
] |
|
} |
|
} |
|
}, |
|
"workspaceSymbolProvider": true |
|
}, |
|
"serverInfo": { |
|
"name": "rust-analyzer", |
|
"version": "3022a2c3a 2021-05-25 dev" |
|
} |
|
} |
|
} |
|
)"; |
|
std::cout << "Content-Length: " << result.size() << "\r\n\r\n" |
|
<< result; |
|
} |
|
|
|
// Read initialized |
|
{ |
|
std::getline(std::cin, line); |
|
auto size = std::atoi(line.substr(16).c_str()); |
|
std::getline(std::cin, line); |
|
std::string buffer; |
|
buffer.resize(size); |
|
std::cin.read(&buffer[0], size); |
|
std::stringstream ss(buffer); |
|
JSON object(ss); |
|
if(object.string("method") != "initialized") |
|
return 1; |
|
} |
|
|
|
// Read textDocument/didOpen |
|
{ |
|
std::getline(std::cin, line); |
|
auto size = std::atoi(line.substr(16).c_str()); |
|
std::getline(std::cin, line); |
|
std::string buffer; |
|
buffer.resize(size); |
|
std::cin.read(&buffer[0], size); |
|
std::stringstream ss(buffer); |
|
JSON object(ss); |
|
if(object.string("method") != "textDocument/didOpen") |
|
return 1; |
|
} |
|
|
|
// Read textDocument/didChange |
|
{ |
|
std::getline(std::cin, line); |
|
auto size = std::atoi(line.substr(16).c_str()); |
|
std::getline(std::cin, line); |
|
std::string buffer; |
|
buffer.resize(size); |
|
std::cin.read(&buffer[0], size); |
|
std::stringstream ss(buffer); |
|
JSON object(ss); |
|
if(object.string("method") != "textDocument/didChange") |
|
return 1; |
|
} |
|
|
|
// Read and write textDocument/formatting |
|
{ |
|
std::getline(std::cin, line); |
|
auto size = std::atoi(line.substr(16).c_str()); |
|
std::getline(std::cin, line); |
|
std::string buffer; |
|
buffer.resize(size); |
|
std::cin.read(&buffer[0], size); |
|
std::stringstream ss(buffer); |
|
JSON object(ss); |
|
if(object.string("method") != "textDocument/formatting") |
|
return 1; |
|
|
|
std::string result = R"({ |
|
"jsonrpc": "2.0", |
|
"id": 1, |
|
"result": [ |
|
{ |
|
"range": { |
|
"start": { |
|
"line": 0, |
|
"character": 0 |
|
}, |
|
"end": { |
|
"line": 0, |
|
"character": 1 |
|
} |
|
}, |
|
"newText": "" |
|
} |
|
] |
|
} |
|
)"; |
|
std::cout << "Content-Length: " << result.size() << "\r\n\r\n" |
|
<< result; |
|
} |
|
|
|
// Read textDocument/didChange |
|
{ |
|
std::getline(std::cin, line); |
|
auto size = std::atoi(line.substr(16).c_str()); |
|
std::getline(std::cin, line); |
|
std::string buffer; |
|
buffer.resize(size); |
|
std::cin.read(&buffer[0], size); |
|
std::stringstream ss(buffer); |
|
JSON object(ss); |
|
if(object.string("method") != "textDocument/didChange") |
|
return 1; |
|
} |
|
|
|
// Read and write textDocument/definition |
|
{ |
|
std::getline(std::cin, line); |
|
auto size = std::atoi(line.substr(16).c_str()); |
|
std::getline(std::cin, line); |
|
std::string buffer; |
|
buffer.resize(size); |
|
std::cin.read(&buffer[0], size); |
|
std::stringstream ss(buffer); |
|
JSON object(ss); |
|
if(object.string("method") != "textDocument/definition") |
|
return 1; |
|
|
|
std::string result = R"({ |
|
"jsonrpc": "2.0", |
|
"id": 2, |
|
"result": [ |
|
{ |
|
"uri": "file://main.rs", |
|
"range": { |
|
"start": { |
|
"line": 0, |
|
"character": 3 |
|
}, |
|
"end": { |
|
"line": 0, |
|
"character": 7 |
|
} |
|
} |
|
} |
|
] |
|
} |
|
)"; |
|
std::cout << "Content-Length: " << result.size() << "\r\n\r\n" |
|
<< result; |
|
} |
|
|
|
// Read and write textDocument/typeDefinition |
|
{ |
|
std::getline(std::cin, line); |
|
auto size = std::atoi(line.substr(16).c_str()); |
|
std::getline(std::cin, line); |
|
std::string buffer; |
|
buffer.resize(size); |
|
std::cin.read(&buffer[0], size); |
|
std::stringstream ss(buffer); |
|
JSON object(ss); |
|
if(object.string("method") != "textDocument/typeDefinition") |
|
return 1; |
|
|
|
std::string result = R"({ |
|
"jsonrpc": "2.0", |
|
"id": 3, |
|
"result": [ |
|
{ |
|
"uri": "file://main.rs", |
|
"range": { |
|
"start": { |
|
"line": 0, |
|
"character": 4 |
|
}, |
|
"end": { |
|
"line": 0, |
|
"character": 7 |
|
} |
|
} |
|
} |
|
] |
|
} |
|
)"; |
|
std::cout << "Content-Length: " << result.size() << "\r\n\r\n" |
|
<< result; |
|
} |
|
|
|
// Read and write textDocument/implementation |
|
{ |
|
std::getline(std::cin, line); |
|
auto size = std::atoi(line.substr(16).c_str()); |
|
std::getline(std::cin, line); |
|
std::string buffer; |
|
buffer.resize(size); |
|
std::cin.read(&buffer[0], size); |
|
std::stringstream ss(buffer); |
|
JSON object(ss); |
|
if(object.string("method") != "textDocument/implementation") |
|
return 1; |
|
|
|
std::string result = R"({ |
|
"jsonrpc": "2.0", |
|
"id": 4, |
|
"result": [ |
|
{ |
|
"uri": "file://main.rs", |
|
"range": { |
|
"start": { |
|
"line": 0, |
|
"character": 0 |
|
}, |
|
"end": { |
|
"line": 0, |
|
"character": 1 |
|
} |
|
} |
|
}, |
|
{ |
|
"uri": "file://main.rs", |
|
"range": { |
|
"start": { |
|
"line": 1, |
|
"character": 0 |
|
}, |
|
"end": { |
|
"line": 1, |
|
"character": 1 |
|
} |
|
} |
|
} |
|
] |
|
} |
|
)"; |
|
std::cout << "Content-Length: " << result.size() << "\r\n\r\n" |
|
<< result; |
|
} |
|
|
|
// Read and write textDocument/references |
|
{ |
|
std::getline(std::cin, line); |
|
auto size = std::atoi(line.substr(16).c_str()); |
|
std::getline(std::cin, line); |
|
std::string buffer; |
|
buffer.resize(size); |
|
std::cin.read(&buffer[0], size); |
|
std::stringstream ss(buffer); |
|
JSON object(ss); |
|
if(object.string("method") != "textDocument/references") |
|
return 1; |
|
|
|
std::string result = R"({ |
|
"jsonrpc": "2.0", |
|
"id": 5, |
|
"result": [ |
|
{ |
|
"uri": "file://)" + JSON::escape_string(file_path.string()) + |
|
R"(", |
|
"range": { |
|
"start": { |
|
"line": 2, |
|
"character": 19 |
|
}, |
|
"end": { |
|
"line": 2, |
|
"character": 20 |
|
} |
|
} |
|
}, |
|
{ |
|
"uri": "file://)" + JSON::escape_string(file_path.string()) + |
|
R"(", |
|
"range": { |
|
"start": { |
|
"line": 1, |
|
"character": 8 |
|
}, |
|
"end": { |
|
"line": 1, |
|
"character": 9 |
|
} |
|
} |
|
} |
|
] |
|
} |
|
)"; |
|
std::cout << "Content-Length: " << result.size() << "\r\n\r\n" |
|
<< result; |
|
} |
|
|
|
// Read and write textDocument/references |
|
{ |
|
std::getline(std::cin, line); |
|
auto size = std::atoi(line.substr(16).c_str()); |
|
std::getline(std::cin, line); |
|
std::string buffer; |
|
buffer.resize(size); |
|
std::cin.read(&buffer[0], size); |
|
std::stringstream ss(buffer); |
|
JSON object(ss); |
|
if(object.string("method") != "textDocument/documentSymbol") |
|
return 1; |
|
|
|
std::string result = R"({ |
|
"jsonrpc": "2.0", |
|
"id": 6, |
|
"result": [ |
|
{ |
|
"name": "main", |
|
"kind": 12, |
|
"tags": "", |
|
"deprecated": false, |
|
"location": { |
|
"uri": "file://main.rs", |
|
"range": { |
|
"start": { |
|
"line": 0, |
|
"character": 0 |
|
}, |
|
"end": { |
|
"line": 3, |
|
"character": 1 |
|
} |
|
} |
|
} |
|
} |
|
] |
|
} |
|
)"; |
|
std::cout << "Content-Length: " << result.size() << "\r\n\r\n" |
|
<< result; |
|
} |
|
|
|
// Read textDocument/didClose |
|
{ |
|
std::getline(std::cin, line); |
|
auto size = std::atoi(line.substr(16).c_str()); |
|
std::getline(std::cin, line); |
|
std::string buffer; |
|
buffer.resize(size); |
|
std::cin.read(&buffer[0], size); |
|
std::stringstream ss(buffer); |
|
JSON object(ss); |
|
if(object.string("method") != "textDocument/didClose") |
|
return 1; |
|
} |
|
|
|
// Read shutdown and respond |
|
{ |
|
std::getline(std::cin, line); |
|
auto size = std::atoi(line.substr(16).c_str()); |
|
std::getline(std::cin, line); |
|
std::string buffer; |
|
buffer.resize(size); |
|
std::cin.read(&buffer[0], size); |
|
std::stringstream ss(buffer); |
|
JSON object(ss); |
|
if(object.string("method") != "shutdown") |
|
return 1; |
|
|
|
std::string result = R"({ |
|
"jsonrpc": "2.0", |
|
"id": 7, |
|
"result": {} |
|
})"; |
|
std::cout << "Content-Length: " << result.size() << "\r\n\r\n" |
|
<< result; |
|
} |
|
|
|
// Read exit |
|
{ |
|
std::getline(std::cin, line); |
|
auto size = std::atoi(line.substr(16).c_str()); |
|
std::getline(std::cin, line); |
|
std::string buffer; |
|
buffer.resize(size); |
|
std::cin.read(&buffer[0], size); |
|
std::stringstream ss(buffer); |
|
JSON object(ss); |
|
if(object.string("method") != "exit") |
|
return 1; |
|
} |
|
} |
|
catch(const std::exception &e) { |
|
std::cerr << e.what() << std::endl; |
|
return 2; |
|
} |
|
}
|
|
|