19 compilerCtx = std::make_shared<yoi::compilerContext>();
31 .setImmediatelyClearupCache(
true)
47 int contentLength = 0;
49 while (std::getline(std::cin, line)) {
51 if (!line.empty() && line.back() ==
'\r')
54 if (line.empty())
break;
56 if (line.rfind(
"Content-Length:", 0) == 0) {
57 std::string lenStr = line.substr(15);
59 size_t pos = lenStr.find_first_not_of(
" \t");
60 if (pos != std::string::npos) lenStr = lenStr.substr(pos);
61 contentLength = std::stoi(lenStr);
65 if (contentLength <= 0)
return "";
68 std::string content(contentLength,
'\0');
69 std::cin.read(&content[0], contentLength);
74 std::ostringstream header;
75 header <<
"Content-Length: " << content.size() <<
"\r\n\r\n";
76 std::cout << header.str() << content << std::flush;
92 {
"error", {{
"code", code}, {
"message", message}}}
111 std::string method = msg.value(
"method",
"");
112 json id = msg.contains(
"id") ? msg[
"id"] :
json();
115 bool isRequest = msg.contains(
"id");
117 if (method ==
"initialize") {
119 }
else if (method ==
"initialized") {
121 }
else if (method ==
"shutdown") {
123 }
else if (method ==
"exit") {
125 }
else if (method ==
"textDocument/didOpen") {
127 }
else if (method ==
"textDocument/didChange") {
129 }
else if (method ==
"textDocument/didClose") {
131 }
else if (method ==
"textDocument/completion") {
133 }
else if (method ==
"textDocument/hover") {
135 }
else if (method ==
"textDocument/definition") {
137 }
else if (method ==
"textDocument/references") {
139 }
else if (method ==
"textDocument/documentSymbol") {
141 }
else if (isRequest) {
143 sendError(
id, -32601,
"Method not found: " + method);
154 if (params.contains(
"rootUri") && params[
"rootUri"].is_string()) {
166 if (params.contains(
"rootPath") && params[
"rootPath"].is_string() &&
workspaceRoot.empty()) {
180 std::filesystem::path hoshiLibPath = hoshiBinPath /
".." /
"lib";
183 std::string globalLib = std::filesystem::canonical(hoshiLibPath, ec).string();
199 }
catch (
const std::exception &e) {
200 std::cerr <<
"[lsp] compiler init failed: " << e.what() << std::endl;
268 switch (diag.severity) {
326 if (result.empty()) {
328 }
else if (result.size() == 1) {
343 return static_cast<int>(v >
static_cast<yoi::indexT>(INT_MAX) ? INT_MAX : v);
381 if (endLine < startLine) endLine = startLine;
382 if (endLine == startLine && endColumn <= startColumn) endColumn = startColumn + 1;
406 auto uri = params[
"textDocument"][
"uri"].get<std::string>();
409 std::vector<DocumentSymbol> result;
411 if (doc && doc->parseSucceeded) {
412 for (
auto &sym : doc->symbols) {
413 if (sym.isLocal)
continue;
418 for (
auto &child : sym.children) {
421 ds.
children.push_back(std::move(childSymbol));
426 for (
auto &local : doc->symbols) {
427 if (!local.isLocal || local.parentName != sym.name ||
428 local.ownerLine != sym.line) {
433 ds.
children.push_back(std::move(localSymbol));
438 result.push_back(ds);
453 if (content.empty()) {
454 if (std::cin.eof())
break;
457 json msg = json::parse(content);
459 }
catch (
const std::exception &e) {
460 std::cerr <<
"[lsp] error: " << e.what() << std::endl;
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
array_t * array
array (stored with pointer to save storage)
CompletionList provide(Document *doc, const Position &pos)
DefinitionResult provide(Document *doc, const Position &pos, const std::string &uri)
void closeDocument(const std::string &uri)
void openDocument(const std::string &uri, const std::string &text, const std::string &languageId, int version)
void setCompilerContext(std::shared_ptr< yoi::compilerContext > ctx)
Document * getDocument(const std::string &uri)
void setProjectIndex(ProjectIndex *index)
void updateDocument(const std::string &uri, const std::string &text, int version)
std::optional< Hover > provide(Document *doc, const Position &pos)
void handleDidOpen(const json ¶ms)
void writeMessage(const std::string &content)
void handleShutdown(const json &id)
void handleDefinition(const json &id, const json ¶ms)
void handleDidChange(const json ¶ms)
void sendNotification(const std::string &method, const json ¶ms)
void sendResponse(const json &id, const json &result)
void handleReferences(const json &id, const json ¶ms)
void handleDidClose(const json ¶ms)
std::string readMessage()
std::string workspaceRoot
void sendError(const json &id, int code, const std::string &message)
std::shared_ptr< yoi::compilerContext > compilerCtx
void handleHover(const json &id, const json ¶ms)
ProjectIndex projectIndex
void handleMessage(const json &msg)
void handleCompletion(const json &id, const json ¶ms)
void handleInitialize(const json &id, const json ¶ms)
void handleInitialized(const json ¶ms)
void handleDocumentSymbol(const json &id, const json ¶ms)
void publishDiagnostics(const std::string &uri, int version)
void addSearchPath(const std::string &path)
#define HOSHI_LANG_VERSION
#define HOSHI_LANG_GIT_COMMIT_HASH
static void extendRangeToInclude(Range &range, const Range &child)
static DocumentSymbol documentSymbolFor(const Symbol &symbol)
static int safeInt(yoi::indexT v)
static lsp::SymbolKind mapSymbolKind(HoshiSymbolKind k)
std::vector< Location > DefinitionResult
std::string wstring2string(const std::wstring &v)
std::wstring string2wstring(const std::string &v)
std::wstring whereIsHoshiLang()
TextDocumentIdentifier textDocument
TextDocumentIdentifier textDocument
std::vector< TextDocumentContentChangeEvent > contentChanges
VersionedTextDocumentIdentifier textDocument
TextDocumentIdentifier textDocument
TextDocumentItem textDocument
std::vector< DocumentSymbol > children
yoi::vec< yoi::Diagnostic > diagnostics
TextDocumentIdentifier textDocument
DiagnosticSeverity severity
std::optional< std::string > source
std::vector< LspDiagnostic > diagnostics
Builder & setBuildType(BuildType buildType)
std::shared_ptr< IRBuildConfig > yield()
Builder & setBuildMode(BuildMode buildMode)
Builder & setBuildPlatform(const yoi::wstr &buildPlatform)
Builder & setBuildArch(const yoi::wstr &buildArch)
Builder & setSearchPaths(const yoi::vec< yoi::wstr > &searchPaths)