36 std::getline(std::cin, line);
40 Logger::Log(
"[fatal] Did not find Content-Length ...\n");
45 std::getline(std::cin, line);
46 std::string content(content_length,
' ');
47 std::cin.read(&content[0], content_length);
60 std::cout << content << std::flush;
66 for (
const SourceId& source : DiagnosticsFiles::Get()) {
68 notification.set_method(
"textDocument/publishDiagnostics");
71 notification.params().set_uri(error_file);
73 USE(notification.params().diagnostics_size());
75 writer(std::move(notification.GetJsonValue()));
77 DiagnosticsFiles::Get() = {};
85class DiagnosticCollector {
87 void AddTorqueMessage(
const TorqueMessage& message) {
88 if (!ShouldAddMessageOfKind(message.kind))
return;
92 auto& notification = GetOrCreateNotificationForSource(
id);
94 Diagnostic diagnostic = notification.params().add_diagnostics();
95 diagnostic.set_severity(ServerityFor(message.kind));
96 diagnostic.set_message(message.message);
97 diagnostic.set_source(
"Torque Compiler");
99 if (message.position) {
100 PopulateRangeFromSourcePosition(diagnostic.range(), *message.position);
104 std::map<SourceId, PublishDiagnosticsNotification>& notifications() {
115 notification.set_method(
"textDocument/publishDiagnostics");
119 notification.params().set_uri(file);
132 if (suppress_lint_messages_)
return false;
137 void PopulateRangeFromSourcePosition(
Range range,
139 range.start().set_line(
position.start.line);
140 range.start().set_character(
position.start.column);
141 range.end().set_line(
position.end.line);
142 range.end().set_character(
position.end.column);
158void SendCompilationDiagnostics(
const TorqueCompilerResult&
result,
160 DiagnosticCollector collector;
163 for (
const TorqueMessage& message :
result.messages) {
164 collector.AddTorqueMessage(message);
167 for (
auto& pair : collector.notifications()) {
169 writer(std::move(notification.GetJsonValue()));
173 const SourceId& source = pair.first;
174 if (source.IsValid()) DiagnosticsFiles::Get().push_back(source);
184 SendCompilationDiagnostics(
result, writer);
194 options.collect_language_server_data =
true;
195 options.force_assert_statements =
true;
199 Logger::Log(
"[info] Finished compilation run ...\n");
205 ResetCompilationErrorDiagnostics(writer);
206 RecompileTorque(writer);
211 response.set_id(request.id());
212 response.result().capabilities().textDocumentSync();
213 response.result().capabilities().set_definitionProvider(
true);
214 response.result().capabilities().set_documentSymbolProvider(
true);
223 writer(std::move(response.GetJsonValue()));
229 request.set_id(2000);
230 request.set_method(
"client/registerCapability");
232 Registration
reg = request.params().add_registrations();
234 reg.registerOptions<DidChangeWatchedFilesRegistrationOptions>();
235 FileSystemWatcher watcher = options.add_watchers();
236 watcher.set_globPattern(
"**/*.tq");
239 reg.set_id(
"did-change-id");
240 reg.set_method(
"workspace/didChangeWatchedFiles");
242 writer(std::move(request.GetJsonValue()));
249 std::vector<std::string>& files = TorqueFileList::Get();
251 for (
const auto& file_json :
252 notification.params().object()[
"files"].ToArray()) {
253 CHECK(file_json.IsString());
258 files.push_back(file_json.ToString());
261 RecompileTorqueWithDiagnostics(writer);
267 response.set_id(request.id());
275 response.SetNull(
"result");
276 writer(std::move(response.GetJsonValue()));
282 request.params().position().character());
285 SourcePosition definition = *maybe_definition;
286 response.result().SetTo(definition);
288 response.SetNull(
"result");
291 writer(std::move(response.GetJsonValue()));
294void HandleChangeWatchedFilesNotification(
298 RecompileTorqueWithDiagnostics(writer);
304 response.set_id(request.id());
310 DCHECK(symbol->IsUserDefined());
311 if (symbol->IsMacro()) {
312 Macro* macro = Macro::cast(symbol);
313 SymbolInformation info = response.add_result();
314 info.set_name(macro->ReadableName());
316 info.location().SetTo(macro->Position());
317 }
else if (symbol->IsBuiltin()) {
318 Builtin* builtin = Builtin::cast(symbol);
319 SymbolInformation info = response.add_result();
320 info.set_name(builtin->ReadableName());
322 info.location().SetTo(builtin->Position());
323 }
else if (symbol->IsGenericCallable()) {
324 GenericCallable*
generic = GenericCallable::cast(symbol);
325 SymbolInformation info = response.add_result();
326 info.set_name(generic->name());
328 info.location().SetTo(generic->Position());
329 }
else if (symbol->IsTypeAlias()) {
330 const Type* type = TypeAlias::cast(symbol)->type();
334 SymbolInformation sym = response.add_result();
335 sym.set_name(type->ToString());
337 sym.location().SetTo(symbol->Position());
342 USE(response.result_size());
344 writer(std::move(response.GetJsonValue()));
356 if (!request.has_method()) {
357 Logger::Log(
"[info] Unhandled response with id ", request.id(),
"\n\n");
361 const std::string
method = request.method();
362 if (
method ==
"initialize") {
363 HandleInitializeRequest(
365 }
else if (
method ==
"initialized") {
366 HandleInitializedNotification(writer);
367 }
else if (
method ==
"torque/fileList") {
368 HandleTorqueFileListNotification(
370 }
else if (
method ==
"textDocument/definition") {
371 HandleGotoDefinitionRequest(
373 }
else if (
method ==
"workspace/didChangeWatchedFiles") {
374 HandleChangeWatchedFilesNotification(
377 }
else if (
method ==
"textDocument/documentSymbol") {
378 HandleDocumentSymbolRequest(
static V8_EXPORT_PRIVATE std::optional< SourcePosition > FindDefinition(SourceId source, LineAndColumn pos)
static const Symbols & SymbolsForSourceId(SourceId id)
static void Log(Args &&... args)
static SourceId GetSourceId(const std::string &path)
static std::string AbsolutePath(SourceId file)
static SourceId Invalid()
JsonValue & GetJsonValue()
#define EXPORT_CONTEXTUAL_VARIABLE(VarName)
DirectHandle< JSReceiver > options
ZoneVector< RpoNumber > & result
std::map< SourceId, PublishDiagnosticsNotification > notifications_
bool suppress_lint_messages_
Range(V< T >, V< T >, V< T >) -> Range< T >
ResponseArrayResult< SymbolInformation > DocumentSymbolResponse
Request< DocumentSymbolParams > DocumentSymbolRequest
void WriteMessage(JsonValue message)
Request< DidChangeWatchedFilesParams > DidChangeWatchedFilesNotification
Request< TextDocumentPositionParams > GotoDefinitionRequest
Response< InitializeResult > InitializeResponse
static const size_t kContentLengthSize
std::function< void(JsonValue)> MessageWriter
Request< RegistrationParams > RegistrationRequest
std::string SerializeToString(const JsonValue &value)
Response< Location > GotoDefinitionResponse
constexpr const char * kProtocolLineEnding
Request< InitializeParams > InitializeRequest
static const char kContentLength[]
void HandleMessage(JsonValue raw_message, MessageWriter writer)
Request< FileListParams > TorqueFileListNotification
JsonParserResult ParseJson(const std::string &input)
Request< PublishDiagnosticsParams > PublishDiagnosticsNotification
void CompilationFinished(TorqueCompilerResult result, MessageWriter writer)
TorqueCompilerResult CompileTorque(const std::string &source, TorqueCompilerOptions options)
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
static LineAndColumn WithUnknownOffset(int line, int column)
std::string output_directory