From bdafccbce6210a699a6cf8608cc7dcf626a486e6 Mon Sep 17 00:00:00 2001 From: ykiko Date: Wed, 11 Sep 2024 18:41:12 +0800 Subject: [PATCH] Fix Reflection.h. --- include/Protocol/Basic.h | 22 +++++------ include/Protocol/Document.h | 22 +++++++++++ include/Protocol/Protocol.h | 1 + include/Protocol/SemanticTokens.h | 5 +++ include/Server/Scheduler.h | 2 +- include/Support/JSON.h | 4 +- include/Support/Reflection.h | 65 ++++++++++++++++++++++++++++--- src/Server/Scheduler.cpp | 17 ++++++++ src/Server/Server.cpp | 2 +- 9 files changed, 117 insertions(+), 23 deletions(-) create mode 100644 include/Protocol/Document.h diff --git a/include/Protocol/Basic.h b/include/Protocol/Basic.h index b5311ca7..f935c6ae 100644 --- a/include/Protocol/Basic.h +++ b/include/Protocol/Basic.h @@ -1,21 +1,9 @@ #pragma once -#include -#include -#include -#include +#include namespace clice::protocol { -// reflectable struct definition -template -struct Record : Ts... {}; - -#define CLICE_RECORD(name, ...) \ - struct name##Body; \ - using name = Record<__VA_ARGS__, name##Body>; \ - struct name##Body - /// range in [-2^31, 2^31- 1] using integer = std::int32_t; @@ -47,4 +35,12 @@ struct TextDocumentIdentifier { DocumentUri uri; }; +CLICE_RECORD(VersionedTextDocumentIdentifier, TextDocumentIdentifier) { + // The version number of this document. + // + // The version number of a document will increase after each change, + // including undo/redo. The number doesn't need to be consecutive. + integer version; +}; + } // namespace clice::protocol diff --git a/include/Protocol/Document.h b/include/Protocol/Document.h new file mode 100644 index 00000000..c0441dd7 --- /dev/null +++ b/include/Protocol/Document.h @@ -0,0 +1,22 @@ +#pragma once + +#include "Basic.h" + +namespace clice::protocol { + +struct DidOpenTextDocumentParams { + /// The document that was opened. + TextDocumentItem textDocument; +}; + +struct DidChangeTextDocumentParams { + /// The document that did change. The version number points + /// to the version after all provided content changes have + /// been applied. + VersionedTextDocumentIdentifier textDocument; + + // FIXME: + // std::vector contentChanges; +}; + +} // namespace clice::protocol diff --git a/include/Protocol/Protocol.h b/include/Protocol/Protocol.h index ab248b0d..38dd3f30 100644 --- a/include/Protocol/Protocol.h +++ b/include/Protocol/Protocol.h @@ -1,3 +1,4 @@ #pragma once #include "Lifecycle.h" +#include "Document.h" \ No newline at end of file diff --git a/include/Protocol/SemanticTokens.h b/include/Protocol/SemanticTokens.h index 632f8f3a..66fcb4f6 100644 --- a/include/Protocol/SemanticTokens.h +++ b/include/Protocol/SemanticTokens.h @@ -45,4 +45,9 @@ struct SemanticTokensOptions { bool full = true; }; +struct SemanticTokensParams { + /// The text document. + TextDocumentIdentifier textDocument; +}; + } // namespace clice::protocol diff --git a/include/Server/Scheduler.h b/include/Server/Scheduler.h index 1f974458..981e71e0 100644 --- a/include/Server/Scheduler.h +++ b/include/Server/Scheduler.h @@ -17,7 +17,7 @@ private: }; public: - void dispatch(llvm::StringRef method, llvm::Value value); + void dispatch(std::string_view method, json::Value value); private: llvm::StringMap files; diff --git a/include/Support/JSON.h b/include/Support/JSON.h index 8952789e..be902dc9 100644 --- a/include/Support/JSON.h +++ b/include/Support/JSON.h @@ -61,13 +61,13 @@ json::Value serialize(const Value& value) { template Value deserialize(const json::Value& object) { if constexpr(std::is_same_v) { - return object.getAsBoolean().value(); + return Value{object.getAsBoolean().value()}; } else if constexpr(is_integral_v || std::is_enum_v) { return object.getAsInteger().value(); } else if constexpr(std::is_floating_point_v) { return object.getAsNumber().value(); } else if constexpr(is_string_v) { - return object.getAsString().value(); + return Value{object.getAsString().value()}; } else if constexpr(is_array_v) { Value array; for(const auto& element: *object.getAsArray()) { diff --git a/include/Support/Reflection.h b/include/Support/Reflection.h index cf075966..d3e01b1b 100644 --- a/include/Support/Reflection.h +++ b/include/Support/Reflection.h @@ -163,22 +163,75 @@ struct Storage { inline static T value; }; +template +struct replace_cv_ref; + +template +struct replace_cv_ref { + using type = Target&; +}; + +template +struct replace_cv_ref { + using type = Target&&; +}; + +template +struct replace_cv_ref { + using type = const Target&; +}; + +template +struct replace_cv_ref { + using type = const Target&&; +}; + +template +using replace_cv_ref_t = typename replace_cv_ref::type; + } // namespace clice::impl namespace clice { +template +struct Record; + +template +constexpr inline bool is_record_v = false; + +template +constexpr inline bool is_record_v> = true; + +#define CLICE_RECORD(name, ...) \ + struct name##Body; \ + using name = Record<__VA_ARGS__, name##Body>; \ + struct name##Body + template concept Reflectable = std::is_aggregate_v> && std::is_default_constructible_v>; template constexpr void for_each(Object&& object, const Callback& callback) { using T = std::decay_t; - constexpr auto count = impl::member_count(); - auto members = impl::collcet_members(object); - constexpr auto static_members = impl::collcet_members(impl::Storage::value); - [&](std::index_sequence) { - (callback(impl::member_name(static_members)>(), *std::get(members)), ...); - }(std::make_index_sequence{}); + if constexpr(is_record_v) { + T::for_each(std::forward(object), callback); + } else { + constexpr auto count = impl::member_count(); + auto members = impl::collcet_members(object); + constexpr auto static_members = impl::collcet_members(impl::Storage::value); + [&](std::index_sequence) { + (callback(impl::member_name(static_members)>(), *std::get(members)), ...); + }(std::make_index_sequence{}); + } } +// reflectable struct definition +template +struct Record : Ts... { + template + static void for_each(Object&& object, const Callback& callback) { + (clice::for_each(static_cast>(object), callback), ...); + } +}; + }; // namespace clice diff --git a/src/Server/Scheduler.cpp b/src/Server/Scheduler.cpp index b1246187..c903edda 100644 --- a/src/Server/Scheduler.cpp +++ b/src/Server/Scheduler.cpp @@ -1,2 +1,19 @@ #include +#include +#include +namespace clice { + +void Scheduler::dispatch(std::string_view method, json::Value value) { + if(method == "textDocument/didOpen") { + auto params = json::deserialize(value); + } else if(method == "textDocument/didChange") { + auto params = json::deserialize(value); + } else if(method == "textDocument/semanticTokens/full") { + auto params = json::deserialize(value); + } else { + spdlog::error("unknown method: {}", method); + } +} + +} // namespace clice diff --git a/src/Server/Server.cpp b/src/Server/Server.cpp index 32acd601..1c94f91b 100644 --- a/src/Server/Server.cpp +++ b/src/Server/Server.cpp @@ -139,7 +139,7 @@ void Server::handleMessage(std::string_view message) { if(auto handler = handlers.find(method); handler != handlers.end()) { handler->second(*id, *params); } else { - spdlog::error("Method not found: {}", method); + scheduler.dispatch(method, *params); } }