From a4a07120a1524fbb8b16c79e8ccb8cacb635c954 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 7 May 2018 20:59:08 -0700 Subject: [PATCH] Reflect optional by Brandon Tolsch --- src/messages/ccls_call_hierarchy.cc | 5 ++++- src/messages/ccls_inheritance_hierarchy.cc | 5 ++++- src/messages/ccls_member_hierarchy.cc | 5 ++++- src/messages/text_document_hover.cc | 18 ++++-------------- src/messages/workspace_execute_command.cc | 8 -------- src/serializer.h | 22 ++++++++++++++++++++++ 6 files changed, 38 insertions(+), 25 deletions(-) diff --git a/src/messages/ccls_call_hierarchy.cc b/src/messages/ccls_call_hierarchy.cc index ffcca708..c15e1122 100644 --- a/src/messages/ccls_call_hierarchy.cc +++ b/src/messages/ccls_call_hierarchy.cc @@ -79,7 +79,10 @@ MAKE_REFLECT_STRUCT(Out_CclsCallHierarchy::Entry, callType, numChildren, children); -MAKE_REFLECT_STRUCT(Out_CclsCallHierarchy, jsonrpc, id, result); +MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsCallHierarchy, + jsonrpc, + id, + result); bool Expand(MessageHandler* m, Out_CclsCallHierarchy::Entry* entry, diff --git a/src/messages/ccls_inheritance_hierarchy.cc b/src/messages/ccls_inheritance_hierarchy.cc index 2f4d83be..3f960544 100644 --- a/src/messages/ccls_inheritance_hierarchy.cc +++ b/src/messages/ccls_inheritance_hierarchy.cc @@ -60,7 +60,10 @@ MAKE_REFLECT_STRUCT(Out_CclsInheritanceHierarchy::Entry, location, numChildren, children); -MAKE_REFLECT_STRUCT(Out_CclsInheritanceHierarchy, jsonrpc, id, result); +MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsInheritanceHierarchy, + jsonrpc, + id, + result); bool Expand(MessageHandler* m, Out_CclsInheritanceHierarchy::Entry* entry, diff --git a/src/messages/ccls_member_hierarchy.cc b/src/messages/ccls_member_hierarchy.cc index 8654ed01..dd075c39 100644 --- a/src/messages/ccls_member_hierarchy.cc +++ b/src/messages/ccls_member_hierarchy.cc @@ -59,7 +59,10 @@ MAKE_REFLECT_STRUCT(Out_CclsMemberHierarchy::Entry, location, numChildren, children); -MAKE_REFLECT_STRUCT(Out_CclsMemberHierarchy, jsonrpc, id, result); +MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsMemberHierarchy, + jsonrpc, + id, + result); bool Expand(MessageHandler* m, Out_CclsMemberHierarchy::Entry* entry, diff --git a/src/messages/text_document_hover.cc b/src/messages/text_document_hover.cc index 455c61c5..eacd662b 100644 --- a/src/messages/text_document_hover.cc +++ b/src/messages/text_document_hover.cc @@ -57,20 +57,10 @@ struct Out_TextDocumentHover : public lsOutMessage { std::optional result; }; MAKE_REFLECT_STRUCT(Out_TextDocumentHover::Result, contents, range); -void Reflect(Writer& visitor, Out_TextDocumentHover& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(jsonrpc); - REFLECT_MEMBER(id); - if (value.result) - REFLECT_MEMBER(result); - else { - // Empty optional<> is elided by the default serializer, we need to write - // |null| to be compliant with the LSP. - visitor.Key("result"); - visitor.Null(); - } - REFLECT_MEMBER_END(); -} +MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_TextDocumentHover, + jsonrpc, + id, + result); struct Handler_TextDocumentHover : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } diff --git a/src/messages/workspace_execute_command.cc b/src/messages/workspace_execute_command.cc index a96360f3..8c1327c1 100644 --- a/src/messages/workspace_execute_command.cc +++ b/src/messages/workspace_execute_command.cc @@ -20,14 +20,6 @@ struct Out_WorkspaceExecuteCommand }; MAKE_REFLECT_STRUCT(Out_WorkspaceExecuteCommand, jsonrpc, id, result); -void Reflect(Writer& visitor, Out_WorkspaceExecuteCommand& value) { - REFLECT_MEMBER_START(); - REFLECT_MEMBER(jsonrpc); - REFLECT_MEMBER(id); - REFLECT_MEMBER(result); - REFLECT_MEMBER_END(); -} - struct Handler_WorkspaceExecuteCommand : BaseMessageHandler { MethodType GetMethodType() const override { return kMethodType; } diff --git a/src/serializer.h b/src/serializer.h index 69b524dd..3e1bfe87 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -19,6 +19,7 @@ enum class SerializeFormat { Binary, Json }; struct JsonNull {}; +struct mandatory_optional_tag {}; class Reader { public: @@ -77,6 +78,8 @@ struct IndexFile; #define REFLECT_MEMBER_START() ReflectMemberStart(visitor, value) #define REFLECT_MEMBER_END() ReflectMemberEnd(visitor, value); #define REFLECT_MEMBER(name) ReflectMember(visitor, #name, value.name) +#define REFLECT_MEMBER_MANDATORY_OPTIONAL(name) \ + ReflectMember(visitor, #name, value.name, mandatory_optional_tag{}) #define REFLECT_MEMBER2(name, value) ReflectMember(visitor, name, value) #define MAKE_REFLECT_TYPE_PROXY(type_name) \ @@ -93,6 +96,8 @@ struct IndexFile; } #define _MAPPABLE_REFLECT_MEMBER(name) REFLECT_MEMBER(name); +#define _MAPPABLE_REFLECT_MEMBER_MANDATORY_OPTIONAL(name) \ + REFLECT_MEMBER_MANDATORY_OPTIONAL(name); #define MAKE_REFLECT_EMPTY_STRUCT(type, ...) \ template \ @@ -109,6 +114,14 @@ struct IndexFile; REFLECT_MEMBER_END(); \ } +#define MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(type, ...) \ + template \ + void Reflect(TVisitor& visitor, type& value) { \ + REFLECT_MEMBER_START(); \ + MACRO_MAP(_MAPPABLE_REFLECT_MEMBER_MANDATORY_OPTIONAL, __VA_ARGS__) \ + REFLECT_MEMBER_END(); \ + } + // clang-format off // Config has many fields, we need to support at least its number of fields. #define NUM_VA_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,N,...) N @@ -243,6 +256,15 @@ void ReflectMember(Writer& visitor, const char* name, Maybe& value) { } } +template +void ReflectMember(Writer& visitor, + const char* name, + T& value, + mandatory_optional_tag) { + visitor.Key(name); + Reflect(visitor, value); +} + // std::vector template void Reflect(Reader& visitor, std::vector& values) {