Bash++
Bash++ compiler internal documentation
BashppServer.h
Go to the documentation of this file.
1
6#pragma once
7
8#include <iostream>
9#include <thread>
10#include <mutex>
11#include <chrono>
12#include <atomic>
13#include <memory>
14#include <optional>
15#include <unordered_map>
16#include <fstream>
17#include <nlohmann/json.hpp>
18#include <unistd.h>
19
20#include <frozen/string.h>
21#include <frozen/unordered_map.h>
22
23#include "ThreadPool.h"
24#include "ProgramPool.h"
25
26#include "static/Message.h"
27#include "generated/ErrorCodes.h"
28
29#include "generated/CompletionList.h"
30#include "generated/CompletionParams.h"
31
33#include <include/BashVersion.h>
34
35namespace bpp {
36
37using json = nlohmann::json;
38
39template<typename T>
40void printValue(std::ostream& os, const T& value) {
41 os << value;
42}
43
44template<typename... Ts>
45void printValue(std::ostream& os, const std::variant<Ts...>& v) {
46 std::visit([&os](auto&& arg) { os << arg; }, v);
47}
48
49
59 private:
60 pid_t pid = getpid();
61 // Resources
62 std::shared_ptr<std::istream> input_stream;
63 std::shared_ptr<std::ostream> output_stream;
64 std::optional<std::string> socket_path;
65 ThreadPool thread_pool = ThreadPool(std::thread::hardware_concurrency());
66 ProgramPool program_pool = ProgramPool(10); // Maximum 10 programs in the pool
67 std::ofstream log_file;
68
69 // Debouncing didChange notifications
71 std::atomic<uint64_t> change_generation{0};
72 std::atomic<uint64_t> average_reparse_time_in_microseconds{50'000}; // 50ms initial guess
73 std::atomic<uint32_t> debounce_time_in_milliseconds{100}; // Start with 100ms
74 };
75
76 // Map: program main URI -> DebounceState
77 // Used for adaptive debouncing
79 private:
80 std::unordered_map<std::string, std::shared_ptr<DebounceState>> states;
82 std::mutex map_mutex;
83
84 void cleanup() {
85 for (auto it = states.begin(); it != states.end(); ) {
86 if (!pool->has_program(it->first)) {
87 it = states.erase(it);
88 } else {
89 it++;
90 }
91 }
92 }
93 public:
94 DebounceStateMap() = delete;
96 std::shared_ptr<DebounceState> get(const std::string& uri) {
97 std::lock_guard<std::mutex> lock(map_mutex);
98 cleanup(); // Clean up stale entries on every access
99 auto it = states.find(uri);
100 if (it != states.end()) return it->second;
101 auto new_state = std::make_shared<DebounceState>();
102 states[uri] = new_state;
103 return new_state;
104 }
105 };
107 std::atomic<bool> processing_didChange{false};
108
109 void _sendMessage(const std::string& message);
110
111 static std::mutex output_mutex; // Mutex for thread-safe output
112 static std::mutex log_mutex; // Mutex for thread-safe logging
113
114 static const GenericResponseMessage invalidRequestHandler(const GenericRequestMessage& request);
115 static void invalidNotificationHandler(const GenericNotificationMessage& request);
116
117 void processRequest(const GenericRequestMessage& request);
118 void processNotification(const GenericNotificationMessage& notification);
119
121 public:
122 BashppServer();
124
125 void mainLoop();
126
127 void setInputStream(std::shared_ptr<std::istream> stream);
128 void setOutputStream(std::shared_ptr<std::ostream> stream);
129 void setSocketPath(const std::string& path);
130 void setLogFile(const std::string& path);
131 void setTargetBashVersion(const BashVersion& version);
132
133 GenericResponseMessage shutdown(const GenericRequestMessage& request);
134 void cleanup();
135
136 void processMessage(const std::string& message);
137
138 // Request-Response handlers
139 GenericResponseMessage handleInitialize(const GenericRequestMessage& request);
140 GenericResponseMessage handleDefinition(const GenericRequestMessage& request);
141 GenericResponseMessage handleHover(const GenericRequestMessage& request);
142 GenericResponseMessage handleDocumentSymbol(const GenericRequestMessage& request);
143 GenericResponseMessage handleRename(const GenericRequestMessage& request);
144 GenericResponseMessage handleReferences(const GenericRequestMessage& request);
145 GenericResponseMessage handleCompletion(const GenericRequestMessage& request);
146
147 CompletionList handleATCompletion(const CompletionParams& params);
148 CompletionList handleDOTCompletion(const CompletionParams& params);
149
150 // Notification handlers
151 void handleDidOpen(const GenericNotificationMessage& request);
152 void handleDidChange(const GenericNotificationMessage& request);
153 void handleDidChangeWatchedFiles(const GenericNotificationMessage& request);
154 void handleDidClose(const GenericNotificationMessage& request);
155
156 void sendResponse(const GenericResponseMessage& response);
157 void sendNotification(const GenericNotificationMessage& notification);
158
159 void publishDiagnostics(std::shared_ptr<bpp::bpp_program> program);
160
161 void add_include_path(const std::string& path);
162 void set_suppress_warnings(bool suppress);
163
164 template <typename... Args>
165 void log(Args&&... args) {
166 if (!log_file.is_open()) {
167 return; // Not logging
168 }
169 std::lock_guard<std::mutex> lock(log_mutex);
170 log_file << "[" << std::to_string(pid) << "] ";
171 ((printValue(log_file, std::forward<Args>(args))), ...);
172 log_file << std::endl;
173 }
174
175 private:
176 using RequestHandler = GenericResponseMessage (BashppServer::*)(const GenericRequestMessage&);
177 using NotificationHandler = void (BashppServer::*)(const GenericNotificationMessage&);
178
183 static constexpr frozen::unordered_map<frozen::string, RequestHandler, 8> request_handlers = {
184 {"initialize", &BashppServer::handleInitialize},
185 {"textDocument/definition", &BashppServer::handleDefinition},
186 {"textDocument/completion", &BashppServer::handleCompletion},
187 {"textDocument/hover", &BashppServer::handleHover},
188 {"textDocument/documentSymbol", &BashppServer::handleDocumentSymbol},
189 {"textDocument/rename", &BashppServer::handleRename},
190 {"textDocument/references", &BashppServer::handleReferences},
191 {"shutdown", &BashppServer::shutdown}
192 };
193
198 static constexpr frozen::unordered_map<frozen::string, NotificationHandler, 4> notification_handlers = {
199 {"textDocument/didOpen", &BashppServer::handleDidOpen},
200 {"textDocument/didChange", &BashppServer::handleDidChange},
201 {"workspace/didChangeWatchedFiles", &BashppServer::handleDidChangeWatchedFiles},
202 {"textDocument/didClose", &BashppServer::handleDidClose}
203 };
204};
205
206} // namespace bpp
Manages a pool of bpp_program objects for efficient reuse and access.
Definition ProgramPool.h:37
bool has_program(const std::string &file_path)
Check if a program for the given file path exists in the pool.
Definition ProgramPool.cpp:234
A thread pool implementation that manages a pool of worker threads to execute tasks concurrently.
Definition ThreadPool.h:23
Definition BashppServer.h:78
ProgramPool * pool
Definition BashppServer.h:81
void cleanup()
Definition BashppServer.h:84
std::shared_ptr< DebounceState > get(const std::string &uri)
Definition BashppServer.h:96
DebounceStateMap(ProgramPool *program_pool)
Definition BashppServer.h:95
std::unordered_map< std::string, std::shared_ptr< DebounceState > > states
Definition BashppServer.h:80
std::mutex map_mutex
Definition BashppServer.h:82
The main server class for handling LSP requests and notifications.
Definition BashppServer.h:58
void publishDiagnostics(std::shared_ptr< bpp::bpp_program > program)
Definition BashppServer.cpp:313
GenericResponseMessage handleHover(const GenericRequestMessage &request)
Definition handleHover.cpp:10
void(BashppServer::*)(const GenericNotificationMessage &) NotificationHandler
Definition BashppServer.h:177
void processNotification(const GenericNotificationMessage &notification)
Definition BashppServer.cpp:259
void mainLoop()
Definition BashppServer.cpp:159
static std::mutex log_mutex
Definition BashppServer.h:112
DebounceStateMap debounce_states
Definition BashppServer.h:106
GenericResponseMessage handleRename(const GenericRequestMessage &request)
Definition handleRename.cpp:10
pid_t pid
Definition BashppServer.h:60
void sendNotification(const GenericNotificationMessage &notification)
Definition BashppServer.cpp:229
void setSocketPath(const std::string &path)
Definition BashppServer.cpp:129
void processRequest(const GenericRequestMessage &request)
Definition BashppServer.cpp:235
GenericResponseMessage handleDocumentSymbol(const GenericRequestMessage &request)
Definition handleDocumentSymbol.cpp:9
static constexpr frozen::unordered_map< frozen::string, RequestHandler, 8 > request_handlers
Maps request types to the functions that handle them.
Definition BashppServer.h:183
ProgramPool program_pool
Definition BashppServer.h:66
void handleDidClose(const GenericNotificationMessage &request)
Definition handledDidClose.cpp:9
GenericResponseMessage(BashppServer::*)(const GenericRequestMessage &) RequestHandler
Definition BashppServer.h:176
std::optional< std::string > socket_path
Definition BashppServer.h:64
void sendResponse(const GenericResponseMessage &response)
Definition BashppServer.cpp:223
std::atomic< bool > processing_didChange
Definition BashppServer.h:107
ThreadPool thread_pool
Definition BashppServer.h:65
static constexpr frozen::unordered_map< frozen::string, NotificationHandler, 4 > notification_handlers
Maps notification types to the functions that handle them.
Definition BashppServer.h:198
void setOutputStream(std::shared_ptr< std::ostream > stream)
Definition BashppServer.cpp:125
GenericResponseMessage shutdown(const GenericRequestMessage &request)
Definition BashppServer.cpp:305
GenericResponseMessage handleReferences(const GenericRequestMessage &request)
Definition handleReference.cpp:11
std::shared_ptr< std::istream > input_stream
Definition BashppServer.h:62
static void invalidNotificationHandler(const GenericNotificationMessage &request)
Definition BashppServer.cpp:213
std::shared_ptr< std::ostream > output_stream
Definition BashppServer.h:63
void handleDidChange(const GenericNotificationMessage &request)
Definition handleDidChange.cpp:9
void processMessage(const std::string &message)
Definition BashppServer.cpp:275
void handleDidOpen(const GenericNotificationMessage &request)
Definition handleDidOpen.cpp:9
void log(Args &&... args)
Definition BashppServer.h:165
BashppServer()
Definition BashppServer.cpp:15
GenericResponseMessage handleInitialize(const GenericRequestMessage &request)
Definition handleInitialize.cpp:11
void setInputStream(std::shared_ptr< std::istream > stream)
Definition BashppServer.cpp:121
std::ofstream log_file
Definition BashppServer.h:67
GenericResponseMessage handleDefinition(const GenericRequestMessage &request)
Definition handleDefinition.cpp:10
CompletionList handleDOTCompletion(const CompletionParams &params)
Definition handleCompletion.cpp:124
void setLogFile(const std::string &path)
Definition BashppServer.cpp:133
CompletionList handleATCompletion(const CompletionParams &params)
Definition handleCompletion.cpp:75
void handleDidChangeWatchedFiles(const GenericNotificationMessage &request)
Definition handleDidChangeWatchedFiles.cpp:9
void add_include_path(const std::string &path)
Definition BashppServer.cpp:359
static const GenericResponseMessage invalidRequestHandler(const GenericRequestMessage &request)
Definition BashppServer.cpp:209
void cleanup()
Definition BashppServer.cpp:144
CompletionList default_completion_list
Definition BashppServer.h:120
static std::mutex output_mutex
Definition BashppServer.h:111
void setTargetBashVersion(const BashVersion &version)
Definition BashppServer.cpp:140
void _sendMessage(const std::string &message)
Definition BashppServer.cpp:217
~BashppServer()
Definition BashppServer.cpp:119
GenericResponseMessage handleCompletion(const GenericRequestMessage &request)
Definition handleCompletion.cpp:10
void set_suppress_warnings(bool suppress)
Definition BashppServer.cpp:363
Definition bash_case.cpp:8
void printValue(std::ostream &os, const T &value)
Definition BashppServer.h:40
nlohmann::json json
Definition BashppServer.h:37
Represents a Bash version to target for code generation.
Definition BashVersion.h:20
Definition BashppServer.h:70
std::atomic< uint32_t > debounce_time_in_milliseconds
Definition BashppServer.h:73
std::atomic< uint64_t > change_generation
Definition BashppServer.h:71
std::atomic< uint64_t > average_reparse_time_in_microseconds
Definition BashppServer.h:72