|
15 | 15 |
|
16 | 16 | namespace Carbon::LanguageServer { |
17 | 17 |
|
| 18 | +// An adapter for clangd's logging that sends most messages to `error_stream`. |
| 19 | +// Verbose logging is only printed if `vlog_stream` is provided, and will be |
| 20 | +// sent there. |
| 21 | +class Logger : public clang::clangd::Logger { |
| 22 | + public: |
| 23 | + explicit Logger(llvm::raw_ostream* error_stream, |
| 24 | + llvm::raw_ostream* vlog_stream) |
| 25 | + : error_logger_(*error_stream, clang::clangd::Logger::Info), |
| 26 | + vlog_logger_(vlog_stream |
| 27 | + ? std::make_unique<clang::clangd::StreamLogger>( |
| 28 | + *vlog_stream, clang::clangd::Logger::Verbose) |
| 29 | + : nullptr) {} |
| 30 | + |
| 31 | + auto log(Level level, const char* format, |
| 32 | + const llvm::formatv_object_base& message) -> void override { |
| 33 | + if (level != clang::clangd::Logger::Verbose) { |
| 34 | + error_logger_.log(level, format, message); |
| 35 | + } else if (vlog_logger_) { |
| 36 | + vlog_logger_->log(level, format, message); |
| 37 | + } |
| 38 | + } |
| 39 | + |
| 40 | + private: |
| 41 | + clang::clangd::StreamLogger error_logger_; |
| 42 | + std::unique_ptr<clang::clangd::StreamLogger> vlog_logger_; |
| 43 | +}; |
| 44 | + |
18 | 45 | auto Run(FILE* input_stream, llvm::raw_ostream& output_stream, |
19 | | - llvm::raw_ostream& error_stream, DiagnosticConsumer& consumer) |
20 | | - -> bool { |
21 | | - // TODO: Consider implementing a custom logger that splits vlog to |
22 | | - // vlog_stream when provided. For now, this disables verbose logging. |
23 | | - clang::clangd::StreamLogger logger(error_stream, clang::clangd::Logger::Info); |
| 46 | + llvm::raw_ostream& error_stream, llvm::raw_ostream* vlog_stream, |
| 47 | + DiagnosticConsumer& consumer) -> bool { |
| 48 | + // The language server internally uses diagnostics for logging issues, but the |
| 49 | + // clangd parts have their own logging system. We intercept that here. |
| 50 | + Logger logger(&error_stream, vlog_stream); |
24 | 51 | clang::clangd::LoggingSession logging_session(logger); |
25 | 52 |
|
26 | 53 | // Set up the connection. |
27 | 54 | std::unique_ptr<clang::clangd::Transport> transport( |
28 | 55 | clang::clangd::newJSONTransport(input_stream, output_stream, |
29 | 56 | /*InMirror=*/nullptr, |
30 | 57 | /*Pretty=*/true)); |
31 | | - Context context; |
| 58 | + Context context(&consumer); |
32 | 59 | // TODO: Use error_stream in IncomingMessages to report dropped errors. |
33 | 60 | IncomingMessages incoming(transport.get(), &context); |
34 | 61 | OutgoingMessages outgoing(transport.get()); |
|
0 commit comments