#pragma once #include "Compiler/Compiler.h" #include "Server/Async.h" #include "Server/Config.h" #include "Server/Logger.h" #include "Server/Scheduler.h" #include "Server/Protocol.h" #include "Support/Support.h" namespace clice { class Server { public: Server(); int run(int argc, const char** argv); private: using onRequest = llvm::unique_function(json::Value, json::Value)>; using onNotification = llvm::unique_function(json::Value)>; template void addMethod(llvm::StringRef name, async::promise (Server::*method)(json::Value, const Param&)) { requests.try_emplace( name, [this, method](json::Value id, json::Value value) -> async::promise { co_await (this->*method)(std::move(id), json::deserialize(value)); }); } template void addMethod(llvm::StringRef name, async::promise (Server::*method)(const Param&)) { notifications.try_emplace(name, [this, method](json::Value value) -> async::promise { co_await (this->*method)(json::deserialize(value)); }); } private: /// ============================================================================ /// Lifestyle Message /// ============================================================================ async::promise onInitialize(json::Value id, const proto::InitializeParams& params); async::promise onInitialized(const proto::InitializedParams& params); async::promise onShutdown(json::Value id, const proto::None&); async::promise onExit(const proto::None&); /// ============================================================================ /// Document Synchronization /// ============================================================================ async::promise onDidOpen(const proto::DidOpenTextDocumentParams& document); async::promise onDidChange(const proto::DidChangeTextDocumentParams& document); async::promise onDidSave(const proto::DidSaveTextDocumentParams& document); async::promise onDidClose(const proto::DidCloseTextDocumentParams& document); /// ============================================================================ /// Language Features /// ============================================================================ async::promise onGotoDeclaration(json::Value id, const proto::DeclarationParams& params); async::promise onGotoDefinition(json::Value id, const proto::DefinitionParams& params); async::promise onGotoTypeDefinition(json::Value id, const proto::TypeDefinitionParams& params); async::promise onGotoImplementation(json::Value id, const proto::ImplementationParams& params); async::promise onFindReferences(json::Value id, const proto::ReferenceParams& params); async::promise onPrepareCallHierarchy(json::Value id, const proto::CallHierarchyPrepareParams& params); async::promise onIncomingCall(json::Value id, const proto::CallHierarchyIncomingCallsParams& params); async::promise onOutgoingCall(json::Value id, const proto::CallHierarchyOutgoingCallsParams& params); async::promise onPrepareTypeHierarchy(json::Value id, const proto::TypeHierarchyPrepareParams& params); async::promise onSupertypes(json::Value id, const proto::TypeHierarchySupertypesParams& params); async::promise onSubtypes(json::Value id, const proto::TypeHierarchySubtypesParams& params); async::promise onDocumentHighlight(json::Value id, const proto::DocumentHighlightParams& params); async::promise onDocumentLink(json::Value id, const proto::DocumentLinkParams& params); async::promise onHover(json::Value id, const proto::HoverParams& params); async::promise onCodeLens(json::Value id, const proto::CodeLensParams& params); async::promise onFoldingRange(json::Value id, const proto::FoldingRangeParams& params); async::promise onDocumentSymbol(json::Value id, const proto::DocumentSymbolParams& params); async::promise onSemanticTokens(json::Value id, const proto::SemanticTokensParams& params); async::promise onInlayHint(json::Value id, const proto::InlayHintParams& params); async::promise onCodeCompletion(json::Value id, const proto::CompletionParams& params); async::promise onSignatureHelp(json::Value id, const proto::SignatureHelpParams& params); async::promise onCodeAction(json::Value id, const proto::CodeActionParams& params); async::promise onFormatting(json::Value id, const proto::DocumentFormattingParams& params); async::promise onRangeFormatting(json::Value id, const proto::DocumentRangeFormattingParams& params); /// ============================================================================ /// Extension /// ============================================================================ async::promise onContextCurrent(const proto::TextDocumentIdentifier& params); async::promise onContextAll(const proto::TextDocumentIdentifier& params); async::promise onContextSwitch(const proto::TextDocumentIdentifier& params); private: Scheduler scheduler; llvm::StringMap requests; llvm::StringMap notifications; }; } // namespace clice